领域驱动设计是一种设计方法,试图解决的问题是软件的难以理解,难以演化. 采用的方法是围绕业务概念来构建模型.
不过你也可以从两个角度来理解领域驱动设计: 作为设计结果的DDD和作为开发方法的DDD,即 What and How.
作为结果的领域驱动设计是这样一种设计(What): 它建立了一个模型,这个模型具有以下一些特征:
它是用Ubiquitous Language描述的,可以用于未必懂编程的业务专家和开发团队之间的交流,以及开发团队内部的交流,以及代码中类和方法的名字.
它包含了业务领域中一些基本的概念,以及概念之间的关系,它们如何彼此合作,完成业务领域的各种日常工作. 这些概念是与软件无关的,无论你有没有用软件来建模它们,它们每天都出现在从业人员的头脑中,交谈中,公司的账本中. 换句话说,它反映了这个领域的知识. 任何理解了这个模型的人,就理解了这个领域是如何运转的.
它很少是一个大而全的模型,因为同一件事物,在不同的业务场景中有不同的概念,术语,角色. 同一份数据,在不同的场景中也有不同的含义和解读. 因此,模型里的概念按照应用场景自然的分组,它们与另外场景中的概念的关联则通过一种内在的映射来保持.
它是一种说明性的模型,没有实现细节,因为它将软件本身的技术复杂性分离出去,而主要致力于描述业务领域. 这样模型的复杂性就只由业务领域的复杂性来决定. 而通常的结果是这会使它更简单.
这样的模型很容易随着业务的变化而变化,至少不应该比业务本身的变化更困难,更剧烈. 保守一点讲,业务领域的变化比技术领域的变化缓慢的多,模型反映业务,因此也稳定的多. 当业务渐变时,模型只需跟随做简单的调整. 业务其实并不复杂,无论有没有软件支持,每个领域每天都实际发生着数以亿计的从财务的角度可以追溯的,从从业人员的角度可以理解的,从管理者的角度可以掌控的业务. 软件却难以正确表达的原因不在于业务本身多复杂,而在于我们用的工具,用的方法. DDD试图分离实现(solution domain)的复杂性,还原业务(problem domain)的简单性,并提供了相应的工具和方法支持.
这个模型描绘的前景是激动人心的,但是如何实现 (How)? 我们需要实现技术的支持和开发过程实践的支持
书里描述了一些通用的构造块(Building Block),即实现技术的支持:
Entity,Value Object and Aggregate
Repository and Factory
Layered Architecture,Module and Service etc.
Side-effect-free-function
Intention-revealing-interface,Specification and Assertion etc.
...
当然这些构造块并不是全部,新的模式会不断被开发出来 弥合分析与设计及实现之间的Gap. 这些构造块也不是必需的. 虽然Eric在书里说设计必须考虑实现,但实现并不非得就是书里提供的构造块,比如 Entity,Value Object,Repository. 反过来说也可以: 用了Entity,Repository等并不一定意味着你就是在进行DDD. 事实上,类似Entity和Value Object这样的基本概念上的区别,Side effect free function这样的常识,是任何一种设计,任何一种设计方法都应该考虑的.
而更重要的是,开发过程中哪些实践可以支持DDD的实现? 事实上这一部分是DDD的核心,甚至你可以把它理解为What而不是How. 因此描述可以反过来: 我们无法保证最终能得出一个完美的领域模型,我们只能在开发过程中尽力去改进我们手头的模型,然后顺其自然. 因此如何改进模型才是关键,DDD提供了一些基本的方法来促成这种改进.
开发团队与领域专家的合作: 头脑风暴,草图,持续学习,知识消化...
模型作为统一语言: 捕捉语言的不一致性; 通过对话改进模型.
绑定模型与设计实现: 消除分析和设计之间的Gap; 建模人员同时负责实现
把隐含概念转变为显式概念: 倾听表达用语,检查不协调之处,研究矛盾之处,查阅书籍,不断尝试重构
借力分析模式
借力设计模式,尤其是类似策略模式这样偏重于模型概念而不是实现的模式.
更深层次的重构: 组建探索团队,抓住每个模型与现实不匹配的时机,将危机视为机会.
...
然而我们通常面临更多的现实约束,比如我们不是每次都是从头开始建造一个新的系统,我们不得不与遗留系统进行集成; 也不是只有我们一个开发团队,我们需要与其他团队合作. Eric将解决这部分问题的方法叫做战略性设计(Strategic Design)
系统涉及面广,规模庞大: Bounded Context,Context Map,System Metaphor,Responsibility Layers,Knowledge Level
多个团队并行开发,彼此需要交互: Shared Kernel,Customer/Supplier Team,Conformist,Anticorruption Layer
有另外的系统(通常是遗留的)需要集成: Anticorruption Layer,各走各路,Open Host Service,Published Language
有限的资源,无限的问题: 好钢用在刀刃上,Distill Core Domain
这确实是最困难的一部分,如果在战略上选择了不合适的方向,则前面的构造块,领域模型只能算是局部优化. TaoWen说DDD这本书只看第四部分就可以了,这也是一种Distill Core Domain吧.