1、DDD1.为什么选择DDDDDD和系统解耦2.3.DDD和统一语言总结4.我们为什么选择DDDY轴扩展性成为瓶颈影响Y轴扩展的两个因素这意味着Y轴的扩展要灵活我们为什么选择DDD问题一:领域模型不合理错误的数据结构错误的业务约束产品经理关注上层的业务流程和交互缺乏业务语义的模型没有发现隐式的概念程序员关注技术实现我们为什么选择DDD问题二:系统功能间的各种耦合Data CouplingStamp CouplingContent CouplingCommon Coupling耦合的类型但是DDD落地很难让整个团队弄清楚复杂而抽象的方法论,太难了那怎么办?简化,小步,例子多而是面向对象分析和设计最
2、先要普及的不是DDD| 二十多年前人们就推崇用值对象了| 那时DDD还没有诞生降低认知负担提升可读性比如电话号码的校验https:/riehle.org/computer-science/research/1998/ubilab-tr-1998-10-1.htmlPrimitive Obsession| 基本类型偏执| 2000年后面会有实际的例子这种坏味道是指用基本类型来表示领域概念,比如用字符型来表示电话号码、邮政编码等解决办法是定义明确ValueObject。| 实体和聚合早就被广泛认可了| Since|1997年| 很多原则和模式在系统级别依旧有效设计原则设计模式依赖倒置开放封闭单一职
3、责信息隐藏工厂适配器策略状态分层架构整洁架构/洋葱模型端口适配器架构 CQRS| 面向对象富血模型没落史| 背后的驱动力专业的单机软件向以数据为中心的网络软件的演变| 1980s,Smalltalk/C+ 带领下面向对象广泛流行| 1991,Visual Basic 出现属性和属性列表功能| 1992-1995,可视化工具和IDE遍地开花| 1996,JDK1.0发布| 1997,JavaBean规范发布| 1998 -,Java和.NET平台出现大量的通过反射| 机制处理对象属性的工具和框架FROM 实现领域驱动设计理论上,使用DDD并不一定要通过面向对象,但实战中,使用面向对象进行分析设计
4、是最务实的。那么,DDD在面向对象之外还带来了哪些新的东西?首先要理解的是限界上下文该了解些DDD最核心的概念了| 案例分析1:概念不能穿透上下文1除了更好的表意性外有更好的扩展性2| 案例分析1:变化控制在局部RPCRPCAPI适配器u 只有适配器部分的代码需要变化,包含业务逻辑的领域层代码不需要变化u通过编译器的静态类型检查,适配器的变化点很容易识别u适配器充当防腐层(ACL),起到了概念隔离和功能解耦的作用| 案例分析2:上下文关系和Common Coupling读取订单上的标记MS饮订单生产交易服务订“订单标记委员会”分布式大泥团系统的守护神按各系统的需要生产订单时在订单上打标记读取订
5、单上的标记读取订单上的标记标记太多位,含义二义性,新增需求改动的系统太多,影响范围难以界定,沟通成本非常高购物卡读取订单上的标记| 案例分析2:上下文关系和Common Coupling自己领域的守护神DDUWMS交易服务清晰的上下文映射关系,下游理解上游的领域概念,上游不理解下游的领域概念,上游制定标准,DUUU订单生产控制中心下游适配标准。订单餐饮DUU D* 在DDD的上下文映射中,我们优先使用这种“客户-供应商”的模式。自己领域的守护神自己领域的守护神自己领域的守护神U购物卡D,下游; U,上游自己领域的守护神| 案例分析2:进一步要避免的问题上游“老好人”,边界没守住,造成Stamp
6、 Coupling下游要保持独立性,需要使用适配器/防腐层数据TMS不需要TMS需要DUUDWMSTMSTMS产品研发TMS产品研发WMS产品研发WMS产品研发| 案例分析1&2:系统间的依赖倒置/ACL保证Data Coupling下游定义的接口(D)下游(U)上游适配上下游接口的实现RPC领域层业务逻辑数据库用户适配器| 案例分析3:上下文级贫血和Control Coupling1.获取订单数据做逻辑判断外部调用或消息外部调用或消息1.给订单状态机输入可枚举的事件订单生产控制中心订单2.设置订单状态3.操作其它系统2.监听得到订单状态的变化3.操作其它系统| 案例分析4:聚合根的作用聚合根
7、是一组实体和值对象的一致性边界。在这个边界之内维护不变条件,即业务规则。这不是DDD引入的新原则,聚合就该如此。DDD的新原则包括:n 通过唯一标识引用其他聚合n 在边界之外使用最终一致性(比如通过领域事件),一个事务只能修改一个聚合聚合的识别很难,领域事件、领域服务和CQRS的正确应用可以减少技术因素对聚合根识别的干扰。这样做的好处是能更好地支持架构的演进其次要理解的是该了解些DDD统一语言最核心的一些概念了| 物理世界在不同上下文代表着| 不同的概念| 领域太复杂,只有在分割的上下文内| 才可能形成统一的语言店仓拣货打包车间厨房| 使用事件风暴形成统一语言隐形概念的挖掘,聚合根的识别等都非
8、常难且难以达成一致,仅仅在方法论上达成一致还不够,我们需要一种容易执行的工具 让开发者做回正常人 控制节奏,慢下来很难但很重要 学会问问题,挖掘隐形概念 命名很难,那就随便给个名字先达成一致统一语言的形成| 代码和分析模型的低表示差异值对象聚合根领域事件普通实体Repository接口Repository实现应用服务| 没有一个完美的ORM可以用 富血模型 聚合根的原则 但带来了糟糕的或不可控的性能 | 权衡 应用层尽可能薄,不包含领域层的业务逻辑 每个聚合根配一个无状态的助手,和聚合根一起体现所有的领域业务逻辑 如果开始分不清代码放在哪一层,可以先实现然后通过重构渐进下沉应用层的方法聚合根助手 聚合根的方的方法 法THANKS