DDD革命性在于,领域模型准确反映了业务语言,传统的J2EE或Spring+Mybatis等事务性编程模型只关心数据,这些数据对象除了简单setter/getter方法外,没有任何业务方法,被比喻为贫血模式。
事务脚本还是领域模型没有绝对的对错之分,CQRS就是对事务脚本和领域蘑菇型两种模式的综合,因为对于Query和报表的场景,使用领域模型往往会把简单的事情弄复杂。
对于简单的业务场景,使用事务脚本的优点是简单、直观、易上手。但对于复杂的业务场景,事务脚本就很难应付,容易造成代码一锅粥,系统的腐化速度和负责性呈指数上升。目前比较有效的治理方法便是领域建模,应为使用了通用语言,使得隐藏的业务逻辑得到显性化表达,是的复杂性治理成为可能。
举个例子
在事务脚本实现中,关于将一名学生升一年级的领域业务逻辑被写在了gradePromoteService的实现里面,而学生信息StudentInfo仅仅是getters和setters的数据结构
1 | public class GradePromoteServiceImpl implements GradePromoteService{ |
上面的代码完全是面向过程的代码风格,同样的业务逻辑,如果用DDD来实现的话
1 | public class GradePromoteServiceImpl implements GradePromoteService{ |
原来在事务脚本中的逻辑,被分散到Domain Service,Domain Entity中去了
DDD最大的好处是:
- 接触到需求第一步就是考虑领域模型,而不是将其切割成数据和行为,然后数据用数据库实现,行为使用服务实现,最后造成需求的首肢分离。DDD让你首先考虑的是业务语言,而不是数据。DDD强调业务抽象和面向对象编程,而不是过程式业务逻辑实现。重点不同导致编程世界观不同。
- 同样,在面向对象的理论中,StudentInfo中的操作都封装在Entity上,提高了内聚性和可重用性。
- 通用语言:“一个团队,一种语言”,这个很重要,将模型作为语言的支柱。确保团队在内部的所有交流中,代码中,画图,写东西,特别是讲话的时候都要使用这种语言。例如账号,转账,透支策略,这些都是非常重要的领域概念,如果这些命名都和我们日常讨论以及PRD中的描述保持一致,将会极大提升代码的可读性,减少认知成本。说到这,稍微吐槽一下我们有些工程师的英语水平,有些神翻译让一些核心领域概念变得面目全非。