2019年3月敏捷印度演讲之一:领域驱动的战略设计


模块化的三大优点是什么?如何使用Strategic DDD实现这些优势? 
演讲PPT点击标题见原文。下面是意译如下:

是不是发现持续递交感觉像一个梦!一个个 噩梦项目?
用户增加一个输入框,竟然需要涉及业务API、规则BPM和ESB以及Data API等各个环节修改。这种反应速度,这种响应需求的效率多低啊?

一个松耦合的软件架构和组织公司架构的标准是符合两个要求:持续递交的效率和线性扩展组织和系统性能的能力!

结构性问题是头等大事,是实现数字化目标的障碍!
我们怎么设计一个社会技术系统(包括软件本身和构建它的团队)到一种最大化迭代质量和速度呢?
增量体系架构的关键是以一个框架为基础适应变化……这个框架就是领域….,通过建模领域,您可以轻松处理对业务领域的变动和更改  -艾伦·霍尔布(@allen holub)

但是这有多难呢?看看微服务实战失败教训:再见微服务:从100个有问题的孩子到1个超级明星
服务之间的边界反而造成了彼此的障碍…一个任务实现涉及很多服务,这导致开发人员抱怨他们的服务被完成任务中其他服务堵塞,并且拒绝为处理这些堵塞提供帮助…

问题来了: 如何对领域进行分组呢?按照特征进行分组的分类法?还是按照处理流程进行分组的拓扑法?但是,番茄属于蔬菜还是水果呢? 科学地说:番茄是一种水果!它匹配植物学定义水果含义。但是,美国最高法院在1893年的尼克斯诉海登一案中裁定:西红柿算作蔬菜-尽管植物学认为它们是水果。为了保护国内,实行了关税,需要对进口蔬菜种植者征税,西红柿就被法院裁定为属于蔬菜

所以,领域的边界是模糊的、是与上下文相关的!在科学上下文:西红柿属于水果;在烹饪上下文:西红柿是蔬菜!

领域建模基础

  • 为每个领域建模的方法很多
  • 感觉上很“明显”的模型反而可能是错误的
  • 上下文定义模型的效用
  • 语言是与语境有关的,与上下文有关!

查找有界上下文
也就是发现领域中独立的部分,查找语言表达中有专门的意义的词语,例如番茄,从而帮助识别有界上下文。一般人以为有界上下文就是子系统和子领域,其实贯穿上下文是一个线索,如同文学小说中贯穿整本书有一个清晰的脉络一样!
有界上下文的定义是:没有共享代码,没有共享数据库,没有大统一的数据模型,没有有界上下文一个团队。

如何发现有界上下文?
第一个办法:通过事件风暴!
按照时间线对领域建模,从时间上将发生的先后事件顺序罗列出来,比如:CFP开放了!演讲话题提交了!CFP关闭了!演讲话题接受了!然后增加更新细节,比如谁让CFP开放了?是主席!谁进行演讲话题提交?是演讲者!
资源推荐:

leanpub.com/introducing_eventstorming eventstorming.com
github.com/mariuszgil/awesome-eventstorming

最后,通过事件风暴串联起所有的上下文!

发现有界上下文第二种方法:试探!
金融系统案例,我们首先沿着业务领域语言,发现这个系统有信用卡、抵押和贷款三个环节,产品这个概念贯穿其中。
为了设计出最佳的架构,你需要了解业务模式 对于这个金融系统,将将系统的各个部分业务高价值和低价值解耦分离,最大化迭代速度,直至ROI投资回报率潜力最大化!让我们从价值这个视角进行分析:财务建议的价值是支持性,而产品是核心价值,支付是通用性。
第三:为社会需求优化,设计系统使为了让建立这些系统的人们更有动力和生产力。有目标,能自主,能掌握可控!社会复杂性与认知负荷的矛盾:如果团队规模太小太少,团队之间容易发生依赖关系;如果团队太多太大,之间沟通导致社会复杂性将最终导致管理崩溃。
第四:需要尊重技术因素:DDD并不意味着忽略技术问题和创造漂亮的模型。技术问题应该会影响你有界的上下文。其他约束考量有遗产系统、性能、可伸缩性、安全性、存储。
最后,也不要忽视用户体验UX!  更大的自主性(自以为是 自说自画)会导致用户体验的破裂
总结一下发现上下文的五种方式:

  1. 沿着领域语言
  2. 沿着业务价值
  3. 为社会需求优化
  4. 尊重技术因素
  5. 不要忽视用户体验

战略设计模式

首先需要判断有用模式和危险模式:
能够从中吸取教训的都是有用的;能够培养分析思维,确定设计权衡的;共识共享语言.
同时认识到:从来没有两种情况完全一样!完整完美的解决方案会培养正义的懒惰心态!(为追求一个完美解决方案,养了一堆架构师高谈阔论!),或者使用以前可运行的经验,没有任何思考!以为我们我们谈论的是一样的,其实不是;以为知道其实不知道!(banq注:佛教里的 无明!)

最常用的是使用业务流程管道模式作为建模起点(比如办一件事情需要经过多少流程环节,把这些环节作为一个个有界上下文),在这个流程中寻找关键事件,也就是代表重要业务发生,在一个上下文或一个阶段的发生的显著变化!(banq注:从动词角度,不是从名词角度发现)

然后,不要停留在这第一步设计,试图从业务流程管道模式切换到能力切片capability slices模式。

流程管道和能力片有什么区别?分别是横向和纵向的区别!比如一个流程设计验证、激活和管理三个流程,每个流程都需要经过控制、指导、宣传三个环节!这三个环节就是能力片(banq注:实际是流程和环节的区别)

那么我们是沿着流程分析还是按照环节分析呢?使用战略设计记分卡!
比如商业航空飞机计划系统:按照业务流程管道模式分析:
1. 路线小组进行旅程计算
2. 机场Fleet小组进行分配计划
3. 机组人员指派机组

如果数据无效-就地修复,比如路线小组负责legs路线取消!机场Fleet负责飞机事故!机组负责空姐指派!

大脑语境(BRAIN CONTEXT),也就是通常抽象思维,为从这个流程中抽象出一个流程规则,这种思维方式问题是:

  • 从上下文抽象出逻辑是坏的
  • 与其他上下文耦合
  • 高变化
  • 团队耦合 + 政治
  • 并不总是反模式,虽然默认是反模式

不要使用领域流程将用户旅程和组织机构混合在一起!组织机构的变化会与流程变化是相关的。

使用分析模式
初级启发式:

  1. 价值:成本效率/降低自主性风险
  2. 社会:要求/破坏变化的巨大惯性
  3. 技术:减轻客户负担,集中复杂性

依赖关系模式
有界上下文将始终有依赖关系。关系模式帮助我们选择最有效的协作方法。经典的DDD关系模式是每个模式都有技术上或社会的特征:比如共享内核是社会的,因为是团队人之间的共享,Open Host 服务是技术上的,防腐层ACL是社会上的。
现代关系模式是:

  1. 内部源码(内部开源模型)
  2. 人员轮换(临时调到其他团队)
  3. 子团队(大团队内流动的小团队)
  4. 合作模式(团队分组方式)
  5. 联盟团队(临时新团队)

一种SEMI-FLUID SUB-TEAMS管理模式:一个开发人员每个月在不同团队中轮换,管理者不变,(banq注:铁打的营盘流水的兵)

其他战略DDD主题

  1. 进化的社会技术模式
  2. 大型系统设计/上部结构
  3. 上下文映射
  4. 对有界上下文进行分类
  5. 技术集成模式

演讲资源:
ntcoding.co.uk/sociotechnical
ntcoding.co.uk/blog
ntcoding.co.uk/speaking
点击标题见原文演讲PPT