鲍勃大爷:先设计对象的行为,再设计数据库的表结构!


将行为模型与数据模型分离。如果可能,请首先根据其行为设计您的业务对象。稍后设计数据库表结构,并使其与业务对象分离。

banq:落实到DDD中:

  1. 根据业务行为的逻辑一致性设计你的DDD聚合中行为,换句话说:DDD聚合根对象的行为是保证聚合内部逻辑一致性的,正如一个组织的领导是维护保证这个组织的利益一致性的!比如订购商品这件事的逻辑一致性在哪里?订购一条条商品条目,然后计算出总金额,总金额=条目金额之和就是逻辑一致性,这是一种数学的一致性,各个商品条目的金额总和=整个订购金额,业务中使用订单这个词语表示这种一致性,同时又表达一种合同锲约,那么订单就可能作为电商系统内部执行相关活动的假设前提,第一性原理,所有支付、发货都是依据订单这个契约的展开。逻辑一致性体现了一种凝聚力;1+2=3加法汇总就是一种逻辑一致性,还有其他数学形式的算法,当然还有小的业务规则和业务约束等。包括在你的if/else中的业务逻辑。事件建模=发现行为动词。
  2. 有了支持逻辑一致性的行为设计以后,再设计支持行为的聚合静态结构,这些结构是用来支持行为实施的,包括可变状态或一系列事件行为集合;如同仓库是用来支持销售或采购一样,虽然仓库很重要,但只是一种静态容器而已。订单是业务术语,用来表达订购活动的逻辑一致性和契约不变性,那么订单自然变成订购活动的聚合根实体,但是更多行业的聚合根实体不是这么直接自然显现的。
  3. 最后再根据设计好的聚合结构去设计数据库表结构,考虑到聚合事务性(也就是逻辑一致性)和数据库ACID的两者统一,同时通过DDD存储库Repository模式将数据库表(包括其代表的DTO数据传输对象和ORM中的实体模型)与代表业务对象的聚合进行分离。

(具体过程可见我的免费演示视频在百度网盘中:https://www.jdon.com/54881)

如果按传统方式去编程,必然是如下两种现象:

  1. 业务逻辑存在SQL中,迫使每次编写SQL时必须热身:幽默图:程序员准备编写SQL前的热身
  2. 通过IF/ELSE/Switch控制流程逻辑,当业务逻辑复杂时:幽默:当你的代码中有多个嵌套if-else语句时

最后,因为实现方式比较不自然,无法接轨需求和通常人的逻辑推理习惯(反逻辑反人性),你的系统变成这样:
https://v.qq.com/x/page/j0971qmz750.html

Kent Beck:从Monolith到微服务:理论与实践
否定OOP的面向数据编程DOP原理
鲍勃大叔实锤:类与数据结构的比较!每个优秀的软件设计师和架构师都需要牢记的问题