《DDD开篇总结》[1]的前三篇已经阐述了几个内容
1.DDD是什么
2.复杂系统的特征
3.DDD如何应对复杂系统
4.模型概念
5.软件开发流程
但一般DDD资料中都会分为两部分讲述:战略和战术,所以按这两种分类,重新归纳整合一下
道
在讨论战略和战术前,先表述一下“道”
DDD是一种软件开发的方法论,任何方法论,都必须落实到“减少代码复杂度”
那么“道”是什么呢?
一直认为DDD的战略就是道,结果搞错了
软件开发的终极“道”就是“高内聚、低耦合”,它是任何有价值思想和方法的具象
如何才能达到这个终极道呢?
1.DRY2.分离关注点
•2.1. 业务和技术分离•2.2. 业务和部署分离•2.3. 变与不变分离
3.缩小依赖范围4.向稳定方向依赖
战略
DDD战略主要包含统一语言和限界上下文
统一语言
在以往OO开发过程中,会经过OOA,再到OOD,复杂系统中,没有人能全方位了解系统并实现系统,术业有专工,专业人士干伟业事,这是正确的
但分工后,团队合作时沟通至关重要,,在整个系统开发过程中,是有一根主线的,那就是业务知识,业务知识在系统落地前经过层层传递,走样变形是常有的事,从开发人员经过多少次的返工情况就很清楚
如果解决这个问题呢?DDD引入了统一语言,把业务名词含义事先确定好,减少不必要的翻译过程,车同轨,书同文,行同伦
这也消除了业务与技术之间的重复,共同使用业务原语对话
代码就是文档,代码就是领域知识
userService.love(Jack, Rose) => Jack.love(Rose) companyService.hire(company,employee) => Company.hire(employee)
界限上下文
界限上下文囊括了实现道的方方面面,如分离关注点,每个上下文围绕一个关注点,通过整洁架构让各层向稳定方向依赖,合理的划分界限,使各个上下文之间减小依赖
说白了界限上下文就是把一个大系统分而治之
界限上下文算是DDD中的核心知识点,但常被技术人员忽视,对于实用主义的程序员来讲,战术常常更吸引人,其实大到微服务,小到实体类,背后都渗透着上下文的概念
引入限界上下文的目的,不在于如何划分边界,而在于如何控制边界
Alberto Brandolini认为bounded context are a mean of safety(限界上下文意味着安全),safety的意思是being in control and no surprise,对限界上下文是可控制的,就意味着你的系统架构与组织结构都是可控的
显然,限界上下文并不是像大多数程序员理解的那样,是模块、服务、组件或子系统,而是你对领域模型、团队合作以及技术风险的控制
限界上下文是“分而治之”架构原则的体现,我们引入它的目的其实为了控制(应对)软件的复杂度,它并非某种固定的设计单元,我们不能说它就是模块、服务或组件,而是通过它来帮助我们做出高内聚低耦合的设计。只要遵循了这个设计,则限界上下文就可能成为模块、服务或组件。所以,文章《Bounded Contexts as a Strategic Pattern Beyond DDD》才会写到:“限界上下文体现的是高层的抽象机制,它并非编程语言或框架的产出工件,而是体现了人们对领域思考的本质。”
战术
对于开发人员而,战术是最实用的,比如聚合、实体、值对象、工厂、仓储、领域事件等等, 使用这些战术组件建模工具,DDD满足了软件真正的技术需求。这些战术设计工具使开发人员能够按照领域专家的思维开发软件
战略部分讲了,界限上下文的思想是核心,在战术组件中都有体现,比如实体,实体就是一个最小上下文,聚合就是相对实体大一点的上下文
但残酷的现实是,花费了大量的精力来学习这些DDD战术组件,却在实现项目中却用不上,为什么呢?因为事务脚本思维太深,分层也大多是从技术角度出发,没有抽象出领域模型,也就是没有OO抽象,没有一个完整的对象,实体都没有,像工厂,值对象也就成了水中花
这也是我们虽然常重构代码,也不过是大类变小类,大函数拆分成小函数,符合一下代码规范,但对整个项目而言,其实没有实质性改进
如何能有实质性改进,对于复杂系统如何运用上这些战术组件呢?
此时,结构性思维发挥作用了
第一步:过程分解,把一个复杂的系统按流程拆解成各个阶段和步骤,这也是事务脚本的强项
第二步:对象建模,过程性拆解虽然可以降低了开发难度,但领域知识被割裂,代码的业务语义也不明确,在这方面OO是强项,提升代码复用性和内聚性
结合这两步,自上而下的结构化分解+自下而上的面向对象建模,过程化分析更好地清理了模型之间的关系,而对象模型提升代码复用性和业务语义表达能力
总结
DDD是一套很好的方法论,有时我们常在理论纯洁性与实战性之间徘徊。这也许是初级阶段常有的纠结点
DDD有适用场景,事务脚本有存在的优势
不能因为现在人们开口闭口都是DDD,就硬要开展DDD
DDD难以落地除了本身带来了很多概念,还需要团队整体素质
软件开发没有银弹,不能偏执于一种理论,实际开发是场硬仗,像混合格斗一样,不在于一招一式是哪门哪派,制敌才是终极目标,所以需要根据自身情况进行裁剪,灵活运用
References
[1]
《DDD开篇总结》: http://www.zhuxingsheng.com/blog/ddd-opening-summary.html