`
chelsea
  • 浏览: 118280 次
  • 来自: ...
社区版块
存档分类
最新评论

领域驱动设计: Understanding DDD

    博客分类:
 
阅读更多

 

无论有没有软件支持, 无论软件是好是坏, 世界各地每个领域每天都发生着数以亿计可以理解的业务

领域驱动设计是一种设计方法, 试图解决的问题是软件的难以理解, 难以演化. 采用的方法是围绕业务概念来构建模型.

不过你也可以从两个角度来理解领域驱动设计: 作为设计结果的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, Value Object, 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吧.

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics