DDD理论学习系列(13)-- 模块
1. 引言
Module,即模块,是指提供特定功能的相对独立的单元。提到模块,你肯定就会想到模块化设计思想,也就是功能的分解和组合。对于简单问题,可以直接构建单一模块的程序。而对于复杂问题,则可以先创建若干个较小的模块,然后将它们组装、链接在一起,从而构成复杂的软件系统。
在DDD中,模块的用途也是如此,通过分解领域模型为不同的模块,以降低领域模型的复杂性,提高领域模型的可读性。
2. DDD中的模块
模块是一个笼统的概念,比较宽泛,为了正确发挥模块的威力,理解模块的概念就十分重要。下面我们从具体的问题着手,来尝试说明模块的概念。
如何对在线商城的顾客进行建模?
对于顾客来说,一般需要维护顾客的个人信息、收货地址、支付方式。这些信息是紧密相关的,不可独立存在。我们可以抽象出三个简单的聚合Customer
、AddressBook
和 Wallet
。那这些类该如何存放呢?是为每一个聚合创建一个文件夹存放还是放在同一个文件夹?我想答案不言而喻。
这三个聚合就是一个模块,一个客户模块。通过定义一个Customer
文件夹,来将相关联的领域对象组合起来。而这个文件夹体现在C#中就是命名空间的概念。
再来看一个问题,如何设计在线商城的支付功能?
支付是在线商城中十分重要的一个环节,设计的好坏直接影响项目的成败。一般来说,针对于支付环节,我们应该单独放到支付子域中去处理,以维护领域的不变性,支付环节对应支付上下文,在支付上下文下,一些领域概念才能更清晰。为了提升支付体验,我们势必要支持多种支付方式,比如支付宝支付、微信支付、其他银行卡支付。在对接某一种支付方式时,我们就应该为其定义单独的模块,保证支付方式的独立性。同样,我们可以选择通过命名空间来实现模块化,也可以类似NopCommerce创建单独的项目来插件化开发集成每一种支付方式。同样,我们也可以将整个支付功能拧出一个单独的支付模块,以便在其他项目中进行共用。
如何集成第三方SDK?
我们知道开源的一大好处是,大牛们分享了一系列高效、实用库或软件,也就是大家常说的“轮子”,比如Hangfire、RabbitMQ、Dapper、Redis等等,我们可以直接开箱即用。但如果项目中集成很多的第三方SDK,如果不加以组织整理,项目的结构就会比较混乱,代码的可读性就大大降低。这个时候我们就可以考虑模块化的去集成第三方SDK,通过对第三方SDK的再封装,来完善代码的组织结构,以达到项目中的统一调用。Abp框架就是通过这种方式来集成比较流行第三方SDK。
通过以上的举例说明,我们可以看到模块可大可小,每个模块都是相对独立的功能单元。在C#中我们可以用命名空间或单独的项目来实现模块。通过模块来组织和封装相关概念,来分解领域模型,以简化领域模型的复杂性。
但不要将模块与子域和限界上下文混淆。在复杂的领域模型中,为了对领域模型中进行准确建模,需要将领域模型拆分成多个子域,每个子域对应一个或多个限界上下文。在限界上下文中,可以将限界上下文中具体的领域概念分解成不同的模块。所以,从子域到限界上下文再到模块,应该是依次包含关系。
3. 模块设计的原则
模块的设计是基于领域模型的,要符合通用语言的表述。其次,模块的设计要符合高内聚低耦合的设计思想。
3.1. 根据领域来组织模块
模块应该由领域的概念来组织,而不是根据通用的组件类型和模式来创建模块。如果将所有的聚合、服务、工厂分别放在独立的模块中,就会有悖于DDD的设计原则,同时还会限制我们创建富有行为的领域模型。这样设计的模块的关注点是在当前的组件和模式上,而不是在领域上。每个模块都应该有适当的类来建模领域的特定方面的概念和功能。
3.2. 基于通用语言
项目中的通用语言除了用来指导实体,值对象、领域服务和领域事件的的命名外,也适用于模块的命名。使用通用语言来为模块命名,可以清晰的反映领域中的概念,且能够明确模块职责。例如,领域中身份认证的概念,我们就可以以Identity
来命名这个模块。
推荐的模块命名规范是:公司名称.项目名称.架构分层.限界上下文.组件类型。
比如对腾讯微信产品的朋友圈模块的领域层可以按以下方式命名:
Tencent.Weixin.Domain.Moment.Models Tencent.Weixin.Domain.Moment.RepositoriesTencent.Weixin.Domain.Moment.ServicesTencent.Weixin.Domain.Moment.Factories
说到这里,你可能会想到mvc的项目结构也是基于模块的思想,比如Models、Views、Controllers、css、js都是放在独立的文件夹中,这其实也是关注点分离的思想,通过模块的分割来达到关注点分离。
3.3. 高内聚低耦合
高内聚低耦合是模块设计的重要思想,模块内高内聚,模块间低耦合。
一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分,这样有利于修改和组合。
4. 总结
模块是对领域模型进行分解后的产物,是相对独立的功能单元,由一系列高内聚的领域对象组成,相对聚合、实体和值对象来说是更高一层的抽象。
模块化的思想大大简化了领域模型的复杂性,即便于我们设计出高内聚低耦合的系统,也便于我们理解系统的设计。
而至于模块的实现,我们既可以通过命名空间来进行分离,也可以使用单独的项目来实现。
参考资料
What are Modules in Domain Driven Design?
相关文章
DDD理论学习系列(1)-- 通用语言
DDD领域驱动之干货 (一)
DDD理论学习系列(2)-- 领域
DDD理论学习系列(3)-- 限界上下文
DDD理论学习系列(4)-- 领域模型
事件总线知多少(2)
DDD理论学习系列(5)-- 统一建模语言
DDD理论学习系列(6)-- 实体
DDD理论学习系列(7)-- 值对象
DDD理论学习系列(8)-- 应用服务&领域服务
DDD理论学习系列(9)-- 领域事件
DDD理论学习系列(10)-- 聚合
DDD理论学习系列(11)-- 工厂
DDD理论学习系列(12)-- 仓储
从事件和DDD入手来构建微服务
DDD领域驱动之干货 (一)
WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例
【DDD/CQRS/微服务架构案例】在Ubuntu 14.04.4 LTS中运行WeText项目的服务端
基于.NET CORE微服务框架 -surging的介绍和简单示例 (开源)
剥析surging的架构思想
基于.NET CORE微服务框架 -谈谈surging的服务容错降级
我眼中的ASP.NET Core之微服务
.NET Core 事件总线,分布式事务解决方案:CAP
原文地址:http://www.cnblogs.com/sheng-jie/p/7266557.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
DDD理论学习系列(13)-- 模块相关推荐
- DDD理论学习系列(6)-- 实体
DDD理论学习系列--案例及目录 1.引言 实体对应的英语单词为Entity.提到实体,你可能立马就想到了代码中定义的实体类.在使用一些ORM框架时,比如Entity Framework,实体作为直接 ...
- DDD理论学习系列(12)-- 仓储
1. 引言 DDD中Repository这个单词,主要有两种翻译:资源库和仓储,本文取仓储之译. 说到仓储,我们肯定就想到了仓库,仓库一般用来存放货物,而仓库一般由仓库管理员来管理.当工厂生产了一批货 ...
- DDD理论学习系列(11)-- 工厂
1.引言 在针对大型的复杂领域进行建模时,聚合.实体和值对象之间的依赖关系可能会变得十分复杂.在某个对象中为了确保其依赖对象的有效实例被创建,需要深入了解对象实例化逻辑,我们可能需要加载其他相关对象, ...
- DDD理论学习系列(9)-- 领域事件
1. 引言 A domain event is a full-fledged part of the domain model, a representation of something that ...
- DDD理论学习系列(8)-- 应用服务amp;amp;领域服务
1. 引言 单从字面理解,不管是领域服务还是应用服务,都是服务.而什么是服务?从SOA到微服务,它们所描述的服务都是一个宽泛的概念,我们可以理解为服务是行为的抽象.从前缀来看,根据DDD的经典分层架构 ...
- DDD理论学习系列(5)-- 统一建模语言
1.引言 上一节讲解了领域模型,领域模型主要是将业务中涉及到的概念以面向对象的思想进行抽象,抽象出实体对象,确定实体所对应的方法和属性,以及实体之间的关系.然后将这些实体和实体之间的关系以某种形式(比 ...
- DDD理论学习系列(4)-- 领域模型
1.引言 我们还是先来拆词理解,领域模型可以拆为"领域"和"模型"二词. 领域:按照我们之前的文章的理解,DDD中的领域是指软件系统要解决的问题,如我们的办公设 ...
- DDD理论学习系列(3)-- 限界上下文
1. 引言 限界上下文可以拆分为两个词,限界和上下文. 限界:是指一个界限,具体的某一个范围. 上下文:个人理解就是语境. 比如我们常说的段子: "我想静静." 这个句子一般是想表 ...
- DDD理论学习系列(2)-- 领域
1. 引言 领域一词,主要有以下两个意思: 一国主权所达之地. 学术思想或社会活动的范围. 不管是指国家的主权范围也好还是学术活动范围,都是在讲一个范围,一个界限. 比如我们常说的,学术领域.思想领域 ...
最新文章
- 1235813找规律第100个数_拓展提优 | 小学数学拓展提优专项训练第9讲:
- 20165203《Java程序设计》第二周Java学习总结
- 中科院罗平演讲全文:自动撰写金融文档如何实现,用 AI 解救“金融民工” | CCF-GAIR 2017
- 简历的正确发音和习惯用法
- css 注入,electron程序,如何在主进程远程页面中注入js及css?
- serlvet中的过滤器filter
- 单调栈思维 2021年度训练联盟热身训练赛第三场——K题	Summer Trip
- Java中的LinkedHashMap
- request获取各种路径总结
- mysql cmd 实时监控_mysql实时监听sql语句
- JavaScript 数据类型梳理
- findpeaks 寻找峰值函数
- 责任分配矩阵和raci的区别_数字音频处理器和调音台的区别是什么
- 戴尔显示rpc服务器,swmm(暴雨管理模型)安装完成后运行显示 RPC服务器不可用
- 手游用户数据分析平台
- 【 Android 10 系统启动 】系列 -- ShutdownThread(关机流程)
- 一部区块链创业者的“燃点” | 《8问》
- 提升嵌入式开发效率小技巧——开发环境配置
- python 估值模型_【中金固收·固收+】隐藏价值的角落:限售股AAP估值及Python实现方法(上)...
- flask--虚拟环境