当前位置: 首页 > 编程学习 > 软件工程 > 领域驱动 > 正文

从零开始使用CodeArt实践最佳领域驱动开发(二)

2018-04-22 来源:博客园/一个人抽烟

4.划分子系统

使用CA编码项目的核心结构是:由多个子系统组成多个不同的服务来提供项目的各种功能。请不要将这里提到的子系统与大家在别的项目实施方法里的概念混为一谈,CA里的子系统概念是完全不一样的,下面我们详细阐述这一点。

同一事物在不同领域里的本质特征是不尽相同的,例如书在销售领域的关注点是价格、好评度、热销情况等。但在阅读领域里,书更多的关注点是页码、每页内容、段落注释等特征。因此,要想用常规的方法在不同领域重用同一个事物模型是非常困难的。CA为了解决这类问题将整个项目切分为多个子系统,每个子系统关注各自领域内的特征。这些子系统是真正实现业务逻辑的地方,子系统之间会存在一定的依赖关系,但是这种依赖关系是良性的,不会影响系统的重用性。也就是说,每个子系统都可以单独拿出来引用到别的项目子系统中扩展重用。开发人员可以根据需要将多个子系统组装在一起构成一个新的服务,这项服务适用于某一个特定领域,例如:

文章子系统 + 汽车子系统 = 提供汽车文集的服务(汽车门户站点)

相册子系统 + 用户子系统 = 提供用户管理个人相册的服务(社交项目)

销售子系统 + 书籍子系统 = 书籍贸易(电商站点)

从层次结构上来讲,服务属于应用层,直接对表现层负责。子系统里的领域对象及业务代码则属于领域模型层。应用层调用领域模型提供的领域方法以便完成业务需求。

一个项目无论规模多么庞大都可以划分成多个规模量为1的子系统,由于这些子系统的代码量足够少,所以可维护性极高。与传统开发的模式相比,CA里的子系统特点如下:

1) 子系统不是抽象的概念而是真实存在的代码集合。在.Net平台里一个子系统体现为一个程序集。

2) 子系统内部仅关注于领域模型的建立,没有任何数据存储的代码。数据的存储由基础设施层里的数据仓储提供。这意味着你可以随时改变存储的机制:切换数据库类型、改变表结构、分布式部署数据库等持久化操作都不会影响到领域模型的改变。

3) 子系统不仅仅用于一个项目,它可以被任意项目使用。以.Net平台为例,子系统有自己所在的解决方案。当其他项目要使用该子系统时,可以以项目引用、程序集引用等方式重用子系统,但绝对不是复制粘贴源代码到新项目里。子系统的源代码只有一份,升级子系统会让所有使用它的项目收益。

4) 多个子系统可以集成工作,一个子系统里的领域模型是可以被其他子系统扩展的。这里说的扩展是指在不破坏原有代码的情况下,以继承、组合等方式扩充领域模型的能力。与这种方式相比,很多传统开发模式里所谓的“二次开发”就是把以前做过的代码、设计过的数据库表复制到新项目里,再更改源代码和表设计以满足新的需求,这根本就不是扩展而是重写。

5) 子系统不能直接用于表现层,它们工作的场所是在应用层的服务里。你可以使用任意技术搭建服务。在.Net平台下可以部署在IIS里,也可以使用专用于CA的服务器端应用程序部署项目的服务。

有了CA开发项目的结构说明和之前分析原始需求的结果,我们可以继续展开会议系统的编码工作了。

根据前文所述,我们要先为“菜单”、“功能”、“用户”、“角色”等事物创建一个服务,服务会提供各种接口以供表现层调用,例如:创建菜单、新增功能描述等服务接口。请注意,把“菜单”、“功能”、“用户”、“角色”这些事物放在同一个服务里未必正确,我们会在后续的开发工作里基于各种原则将服务分离,创建多个服务、多个子系统。但是在眼前我们不必过多考虑这一点,大胆的去做吧。

为服务命名是我们要考虑的第一件事。大家不要忽略命名的重要性,为服务命名、为子系统命名、为领域对象、领域属性、领域方法命名都是需要你认真对待的工作。经过一番思考后,我们认为“菜单”、“功能”、“用户”、“角色”等事物是一个项目里几乎必备的事物,是一切的源头。所以我们引用门户(Portal)这个词作为服务的名称,表示系统的入口,因此服务的全称为PortalService。

PortalService可以接受表现层的请求,处理关于门户方面的调用命令并返回处理结果给表现层使用。这点大家可以联想下调用淘宝提供的接口,淘宝返回数据给你使用的场景。以.Net平台为例,我们为门户服务建立解决方案PortalService的结构如下图:

1) 解决方案文件夹Framework里引用的是CA提供的部分类库,在后续教程里会详细说明这些库的用法。在这里我们只用知道引用的类库是构建服务必不可缺的。

2) 解决方案文件夹Subsystems表示服务需要用到的子系统,目前服务没有引用任何子系统,稍后我们会创建。

3) portal.services.codeart.cn是托管至IIS的门户服务站点,你也可以使用其他技术部署服务,在这里我们以站点为例。

4) PortalService.Application是门户服务的应用程序集,在这个程序集里主要使用子系统提供的应用命令来完成服务的调用,后面会有详细的说明。