应用程序的模块化设计是我们开始接触到应用程序设计时就立即会接触的概念。本系列文章试图将模块化设计从概念到落地进行体系化的讲解。本节开始我们首先介绍应用程序设计中的模块化概念,以及落地这个概念所需要面临的一些挑战。然后本系列文章将推导这些挑战、问题的解决办法,最后进行示例实战。当然最后示例实战的复杂度肯定比前置展示的组织机构模块示例的复杂度要高得多。
模块是一组模型和行为的集合。 模型定义了模块的业务面,行为则驱动模块产生数据变化。
为了保证读者对后续内容的理解能够保持一致,本节内容试图拉平模块化设计的一些基本原则,包括:
遵循这些原则进行模块设计的工作,我们最终将可以得到一个高内聚-低耦合的功能模块。换句话说这些原则都是为设计出高内聚-低耦合的功能模块而服务的。事实上要遵循这些模块设计原则是需要较高的设计能力——至少这些设计原则并没有从表面文字上看到的那么简单。
单一职责原则是指一个模块只负责一件明确的事情,并且负责做好这件事。例如组织机构模块只负责组织机构信息的维护,并不负责用户基本信息的维护。单一职责原则属于这几种设计原则中的前提性原则。用一个更好理解说法进行表述就是,模块功能的边界感:
上图中表达了组织机构模块的边界感,在边界内的模型和行为属于组织机构模块的业务范围,在边界外的模型和行为不属于组织机构模型的业务范围。但真的能这么简单的理解吗?实际上有很多因素会影响模块确认“哪些模型和行为在边界内,哪些在边界外”。举个例子,我们多次讲到“组织机构模块只负责组织机构信息的维护,并不负责用户基本信息的维护”,那么维护用户和组织机构的关联信息,在不在组织机构模块边界范围内呢?
如果说属于,那么就意味着组织机构模块需要明确知晓系统中有哪些用户类型需要和组织机构信息进行关联,并且每新增一种新的用户类型或者每减少一种已有的用户类型,都需要对组织机构模块的业务逻辑进行修改;如果说不属于,那么组织机构没有这些关联信息,就无法再组织机构内构建完整的组织树结构。
再举一个例子,订单功能是应用系统中最常见的一种业务功能,其主要核心就是对订单进行创建、修改、状态维护;那么通知发货模块进行发货处理是否属于订单应该做的事情? 注意,这里说的通知发货而不是发货本身。
要知道通知发货一定是在订单信息满足某种条件后(例如订单金额己经支付,并且本地仓库存在库存),由订单进行触发的下一步业务过程。换句话说,在代码实现的时候就需要订单模块调用发货模块提供的功能;但是如果需求发生变化了呢?如果后续的需求要求订单不止要通知发货模块、还要通知到货模块、还要通知短信模块该怎么办?难道每次有新的模块需要进行通知都对订单模块的功能进行修改吗?现在读者感觉是不是哪里不对了,貌似通知某些后续的具体模块并不应该是订单模块的职责。
开闭原则(Open-Closed Principle,OCP)是在说:模块内部的功能应该对扩展开放、对修改关闭(不允许修改)。这里所说的修改很容易理解,就是需求变化后使用修改代码的方式对现有业务逻辑进行调整,以便兼容原有业务逻辑和新的业务逻辑。但这里说的扩展包括的含义就比较多了,以下调整方式都属于扩展方式:
新增:保留模块现有的代码,在模块内增加新的业务代码来满足新的需求。注意,这里说的新