文字内容
1. 当 DDD 遇上 DCI 张晓⻰龙 中兴通讯资深软件架构师
3. CONTENTS 01 DCI 架构模式 02 DCI 助⼒力力 DDD 战术设计 03 DCI 助⼒力力 DDD 代码落地 04 DDD/DCI 实践案例例
4. DCI 架构模式
5. DCI (Data, Context, Interactive) Data: 描述领域对象,关注系统是什么 Context: 理解业务的主线,知道什么对象应该扮演什么⾓⾊ Interactive: ⽤⾓⾊ Role 来表达,体现系统做什么
6. DCI 视图 Roles Context A inject Context B Domain Object cast Context C
7. DCI 架构模式 Data, Context and Interaction : A New Architectural Approach by James O. Coplien and Trygve Reenskau
8. DCI 助⼒力力 DDD 战术设计
9. DDD 战术设计元素及其关系
10. DCI 与 DDD 的融合 DCI:Data 概念对应 DDD:Aggregate DCI:Context 概念对应 DDD:Domain Service DCI:Role 的概念在 DDD 中没有 ➤ 对 Role 的建模解决了贫⾎模型和充⾎模型之争 ➤ 将 Role 的建模看作 DDD 战术建模的补充
11. Role 的依赖 Role 中属性为系统⾏为相关数据 Aggregate 中属性(实体和值对象)为领域模型相关数据 Role 是⾏为类或接⼜,Aggregate 中的实体和值对象是数据类, Role 没有⾎⾁,⼯作时需要依赖数据类
12. 显式化关系 ⼀个 Aggregate 可以⽀持哪些 Role ⼀个 Role 可以由哪些 Aggregate 扮演 ⼀个场景下哪些 Aggregate 要扮演哪些 Role 当 Aggregate 内部实体⾏为⽐较多时可以嵌套使⽤ DCI 来拆分 和组合
13. 如何拆分 Role 使⽤场景 稳定性
14. 如何组合 Role 依赖注⼊是常⽤的组合⼿段 对于⼀些⾼级语⾔,有更好的组合⼿段: ➤ C++ 中最有效的组合⼿段是多重继承 ➤ Scala 中最有效的组合⼿段是 Traits ➤ Ruby 中最有效的组合⼿段是 Mixin
15. 领域模型:⽆无 Role VO41 VO42 Entity31 Entity43 Entity32 Entity21 Entity33 VO22 VO34 Entity24 Entity23 Entity11 Entity12 AggregateRoot Entity35 VO44
16. 领域模型:有 Role VO41 VO42 Entity31 Entity32 Entity21 Role1 USE_ROLE(Entity00) USE_ROLE(Entity12) VO44 Entity43 Entity11 Entity33 VO22 VO34 Entity24 Entity23 Entity00 AggregateRoot IMPL_ROLE(Entity00) IMPL_ROLE(Entity11) IMPL_ROLE(Entity12) Entity35 Entity12 Role2 USE_ROLE(Entity11) USE_ROLE(Entity12)
17. DCI 助⼒力力 DDD 代码落地
18. 类与对象 学院派: ⼤大类⼤大对象 数量量很少 容易易理理解 ⼯工程派: ⼩小类⼩小对象 数量量很多 容易易修改
19. 扩展使⽤用 DCI 对于⼀个对象来说,不管是否有领域概念与之对应,只要⾏为 很多,都可以应⽤ DCI 的思想进⾏拆分和组合: ➤ 对象对应 DCI:Data ➤ 对象的 Client 对应 DCI:Context ➤ 对象在每个 Client 下的⾏为对应 DCI:Role ➤ 不管是数据类还是⾏为类,我们都按照 Role 的⽅式来交织 ➤ 对象的⼯作仅仅是组合类,并注⼊依赖
20. 正交设计四原则 消除重复 缩⼩小依赖范围 分离变化⽅方向 向稳定的⽅方向依赖 ⾼高内聚 低耦合
21. 七巧板 素材库 变化⽆无穷的图案
22. 设计对象的步骤 查看素材库,确认是否有所需的⾓⾊实现 如果存在,则通过组合⼿段来复⽤ 如果不存在,则编写针对该⾓⾊的特定实现,除了⾃⼰使⽤外, 也成了素材库的⼀部分
23. 重新审视类与对象的关系 类作为⼀种模块化⼿段,遵循⾼内聚,低耦合,让软件易于应对 变化 对象作为⼀种领域对象的的直接映射,解决了过多的类带来的可 理解性问题,让领域可以指导设计,设计真正反映领域;领域对 象需要真正意义上的⽣命周期管理
24. DDD/DCI 实践案例例
25. 需求1:取钱
26. 需求1:流程
27. 需求1:领域模型 Account MoneyCollector Phone USE_ROLE(Balance) USE_ROLE(Phone) USE_ROLE(AccountInfo) Balance AccountInfo Account IMPL_ROLE(AccountInfo) IMPL_ROLE(Balance) IMPL_ROLE(Phone)
28. 运⾏行行时视图 WithdrawMoneyService MoneyCollector Account: Jim
29. 需求2:转账
30. 需求2:流程
31. 需求2:领域模型 Account new MoneySrc USE_ROLE(AccountInfo) USE_ROLE(Balance) USE_ROLE(Phone) new MoneyDest MoneyCollector Phone USE_ROLE(Balance) USE_ROLE(Phone) USE_ROLE(AccountInfo) Balance AccountInfo Account IMPL_ROLE(AccountInfo) IMPL_ROLE(Balance) IMPL_ROLE(Phone) USE_ROLE(AccountInfo) USE_ROLE(Balance) USE_ROLE(Phone)
32. 运⾏行行时视图 WithdrawMoneyService MoneyDest MoneySrc TransferMoneyToLocalService MoneySrc MoneyDest MoneyCollector MoneyCollector Account:'>Account: Jim Account:'>Account: Lucy
33. 需求3:向异地账户转账
34. 需求3:流程
35. 需求3:领域模型 LocalAccount MoneySrc new MoneyDest new modify LocalMoneySrc USE_ROLE(AccountInfo) USE_ROLE(Balance) USE_ROLE(Phone) modify LocalMoneyDest MoneyCollector Phone USE_ROLE(Balance) USE_ROLE(Phone) USE_ROLE(AccountInfo) Balance AccountInfo modify LocalAccount IMPL_ROLE(AccountInfo) IMPL_ROLE(Balance) IMPL_ROLE(Phone) USE_ROLE(AccountInfo) USE_ROLE(Balance) USE_ROLE(Phone)
36. 需求3:领域模型 RemoteAccount MoneyDest new RemoteMoneyDest USE_ROLE(AccountInfo) AccountInfo new RemoteAccount IMPL_ROLE(AccountInfo)
37. 运⾏行行时视图 WithdrawMoneyService MoneySrc MoneyDest TransferMoneyToLocalService MoneyDest MoneySrc MoneyCollector MoneyCollector LocalAccount:'>LocalAccount: Jim LocalAccount:'>LocalAccount: Lucy
38. 运⾏行行时视图 TransferMoneyToRemoteService MoneySrc MoneyDest MoneyDest MoneyCollector LocalAccount: Jim RemoteAccount: Lucy
39. 需求4:从异地账户转⼊入
40. 需求4:流程
41. 需求4:领域模型 RemoteAccount MoneySrc MoneyDest new RemoteMoneySrc RemoteMoneyDest USE_ROLE(AccountInfo) USE_ROLE(AccountInfo) AccountInfo RemoteAccount IMPL_ROLE(AccountInfo)
42. 运⾏行行时视图 TransferMoneyToRemoteService MoneySrc MoneyDest TransferMoneyFromRemoteService MoneyDest MoneySrc MoneyCollector LocalAccount: Jim RemoteAccount: Lucy
43. 物理理设计 base commonrole model obj1 obj2 domain service
44. 代码示例例:Aggregate 定义
45. 代码示例例:Role 定义
46. 代码示例例:Role 实现
47. 代码示例例:Domain Service
48. ⼩小结
49. ⼩小结 DDD 和 DCI 的融合 Role 的拆分原则和组合⼿段 ⼩类⼤对象
50. 案例例源码地址 C++版:https://github.com/agiledragon/transfer-money Go版:https://github.com/agiledragon/transfer-money-go Python版:https://github.com/agiledragon/transfer-money-python 当 DDD 遇上 DCI, 使得软件容易易应对变化,同时 解决了了过多的类带来的可理理解性问题,让领域可以 指导设计,设计真正反映领域,⽽而这才是领域驱动 设计的真正⽬目的和精髓
52. ➤ 张晓⻰龙 @ 中兴通讯 ➤ 架构师,技术教练 ➤ zhangxiaolong1980@126.com ➤ 简书个⼈人主⻚页: http://www.jianshu.com/u/1381dc29fed9 ➤ GitHub个⼈人主⻚页: https://github.com/agiledragon ➤ GitChat认证作者,昵称:agiledragon THANK YOU