DDD和OO的重要区别:上下文重于抽象

21-06-16 banq
DDD领域驱动设计与OO面向对象之间是有区别的,面向对象更注重抽象,从差异中寻找共同点,然后将其抽象出来;而DDD更注重上下文边界,这种边界代表区分差异。其实这是两种不同的思维方式。
女性系统思想家玛丽·凯瑟琳·贝特森的系统观点摘录一文中认为,圣经的旧约是教会人们学习区分差异,而新约则是教人们注重联系,区别与联系是两种不同的思维模型,正主导西方科学发展的不同路径,在区分细分领域,我们细分到量子力学,但是在注重联系关系方向,跨学科的系统科学也正在不断发展。
OO面向对象思想是:首先需要找到Object(当然,中文初学者还是对Object理解有些障碍),从众多对象object找到它们的共性,物以类聚,抽象成类Class。大多数人还停留在这个初期的抽象阶段,养成了逢事喜欢总结抽象的思维习惯,这造成了很多代码都有糟糕的抽象,这加剧了许多人认为抽象本质上是糟糕的感性情绪,甚至认为抽象=过度设计!
而DDD给我们带来了一种完全不同的思路方向,首先应该注重区别,哪怕存在很多重复也在所不惜,不要轻易抽象总结为类class,因为上下文为王
DDD子域与有界上下文的关系一文中,有的一个领域里面可能存在20个有界/限界上下文,看到这么多上下文中重复现象,习惯OO抽象思维的你是否有一种合并它们的冲动呢?
有界上下文的发展是严格按照业务实践的样子去划分的,正确的上下文边界遵循业务的轮廓。不同的区域在不同的时间以不同的速度变化,将概念压缩到单个模型中是有限制和前提条件的,这个前提条件就是:你得先读旧约:事物的区分,然后再读新约:发现区分后的事物之间的联系。
当然banq个人认为还有第三步:找出这些联系中的动态相互作用,它们应该包含一种逻辑一致性,这就是聚合,聚合是将同一上下文内区分后的不同实体合并在一起,合并的依据是他们的当前上下文中涌现Emergence的特征逻辑,注意,这里抽象的依据不是依靠这些实体内部共性,而是因为它们参与了整体系统的涌现。
寻找“先分后合”的抽象方法有很多,例如先允许大量重复代码(因为位于不同上下文中),然后通过重构删除继承关系,删除没有使用过的重复项,然后在相关的地方找到新的抽象。有的人提出使用强制的函数式风格和无状态函数来消除重复,其实函数式编程提出的无状态、不变性、纯度等也都是一种抽象,所以,即使你掌握足够好的 Haskell,人们也很容易地在 FP 语言中提出糟糕的抽象:幽默:程序员耍小聪明导致认知负担 
总之,在DDD中,上下文的边界重于对这些上下文中共同特征的抽象,是最底层逻辑,上下文重要性高于抽象,宁可不抽象,都不能不划分上下文边界,因为在科学认识论中:必须先有上下文的区分,才有可能实现抽象,而且抽象的依据最好是依据动态相互作用关系,而不是静态的数据库外键关联关系。
Boundary > Abastract !


 

5
猜你喜欢