Module,即模块,是指提供特定功能的相对独立的单元。提到模块,你确定就会想到模块化设计思想,也就是功能的分解和组合。对于简单问题,能够直接构建单一模块的程序。而对于复杂问题,则能够先建立若干个较小的模块,而后将它们组装、连接在一块儿,从而构成复杂的软件系统。微信
在DDD中,模块的用途也是如此,经过分解领域模型为不一样的模块,以下降领域模型的复杂性,提升领域模型的可读性。架构
模块是一个笼统的概念,比较宽泛,为了正确发挥模块的威力,理解模块的概念就十分重要。下面咱们从具体的问题着手,来尝试说明模块的概念。mvc
如何对在线商城的顾客进行建模?app
对于顾客来讲,通常须要维护顾客的我的信息、收货地址、支付方式。这些信息是紧密相关的,不可独立存在。咱们能够抽象出三个简单的聚合Customer
、AddressBook
和 Wallet
。那这些类该如何存放呢?是为每个聚合建立一个文件夹存放仍是放在同一个文件夹?我想答案不言而喻。
这三个聚合就是一个模块,一个客户模块。经过定义一个Customer
文件夹,来将相关联的领域对象组合起来。而这个文件夹体如今C#中就是命名空间的概念。
框架
再来看一个问题,如何设计在线商城的支付功能?dom
支付是在线商城中十分重要的一个环节,设计的好坏直接影响项目的成败。通常来讲,针对于支付环节,咱们应该单独放到支付子域中去处理,以维护领域的不变性,支付环节对应支付上下文,在支付上下文下,一些领域概念才能更清晰。为了提高支付体验,咱们势必要支持多种支付方式,好比支付宝支付、微信支付、其余银行卡支付。在对接某一种支付方式时,咱们就应该为其定义单独的模块,保证支付方式的独立性。一样,咱们能够选择经过命名空间来实现模块化,也能够相似NopCommerce建立单独的项目来插件化开发集成每一种支付方式。一样,咱们也能够将整个支付功能拧出一个单独的支付模块,以便在其余项目中进行共用。模块化
如何集成第三方SDK?学习
咱们知道开源的一大好处是,大牛们分享了一系列高效、实用库或软件,也就是你们常说的“轮子”,好比Hangfire、RabbitMQ、Dapper、Redis等等,咱们能够直接开箱即用。但若是项目中集成不少的第三方SDK,若是不加以组织整理,项目的结构就会比较混乱,代码的可读性就大大下降。这个时候咱们就能够考虑模块化的去集成第三方SDK,经过对第三方SDK的再封装,来完善代码的组织结构,以达到项目中的统一调用。Abp框架就是经过这种方式来集成比较流行第三方SDK。微信支付
经过以上的举例说明,咱们能够看到模块可大可小,每一个模块都是相对独立的功能单元。在C#中咱们能够用命名空间或单独的项目来实现模块。经过模块来组织和封装相关概念,来分解领域模型,以简化领域模型的复杂性。
但不要将模块与子域和限界上下文混淆。在复杂的领域模型中,为了对领域模型中进行准确建模,须要将领域模型拆分红多个子域,每一个子域对应一个或多个限界上下文。在限界上下文中,能够将限界上下文中具体的领域概念分解成不一样的模块。因此,从子域到限界上下文再到模块,应该是依次包含关系。
模块的设计是基于领域模型的,要符合通用语言的表述。其次,模块的设计要符合高内聚低耦合的设计思想。
模块应该由领域的概念来组织,而不是根据通用的组件类型和模式来建立模块。若是将全部的聚合、服务、工厂分别放在独立的模块中,就会有悖于DDD的设计原则,同时还会限制咱们建立富有行为的领域模型。这样设计的模块的关注点是在当前的组件和模式上,而不是在领域上。每一个模块都应该有适当的类来建模领域的特定方面的概念和功能。
项目中的通用语言除了用来指导实体,值对象、领域服务和领域事件的的命名外,也适用于模块的命名。使用通用语言来为模块命名,能够清晰的反映领域中的概念,且可以明确模块职责。例如,领域中身份认证的概念,咱们就能够以Identity
来命名这个模块。
推荐的模块命名规范是:公司名称.项目名称.架构分层.限界上下文.组件类型。
好比对腾讯微信产品的朋友圈模块的领域层能够按如下方式命名:
Tencent.Weixin.Domain.Moment.Models Tencent.Weixin.Domain.Moment.Repositories Tencent.Weixin.Domain.Moment.Services Tencent.Weixin.Domain.Moment.Factories
说到这里,你可能会想到mvc的项目结构也是基于模块的思想,好比Models、Views、Controllers、css、js都是放在独立的文件夹中,这其实也是关注点分离的思想,经过模块的分割来达到关注点分离。
高内聚低耦合是模块设计的重要思想,模块内高内聚,模块间低耦合。
一个完整的系统,模块与模块之间,尽量的使其独立存在。也就是说,让每一个模块,尽量的独立完成某个特定的子功能。模块与模块之间的接口,尽可能的少而简单。若是某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分,这样有利于修改和组合。
模块是对领域模型进行分解后的产物,是相对独立的功能单元,由一系列高内聚的领域对象组成,相对聚合、实体和值对象来讲是更高一层的抽象。
模块化的思想大大简化了领域模型的复杂性,即使于咱们设计出高内聚低耦合的系统,也便于咱们理解系统的设计。
而至于模块的实现,咱们既能够经过命名空间来进行分离,也可使用单独的项目来实现。