建模一直是分析的基础部分首先是Eric Evans的理论原则创建和普及阶段;然后是引入领域事件、事件溯源阶段;最后是微服务架构的提出阶段,今天小编就来聊一聊关于ddd 常见模式?接下来我们就一起去研究一下吧!

ddd 常见模式(DDD三个阶段)

ddd 常见模式

DDD的诞生和发展

建模一直是分析的基础部分。

DDD三个阶段

首先是Eric Evans的理论原则创建和普及阶段;然后是引入领域事件、事件溯源阶段;最后是微服务架构的提出阶段。

DDD提出的有界上下文已经将业务的边界划分清楚,所以微服务的实现就顺理成章了。

DDD中的战略模式需要更多的关注,因此,事件风暴等有关组织管理等方面的新事物开始出现。通过事件风暴会议发现领域中的事件,对领域的上下文进行切分,发现其中的聚合,这套方法变得越来越流行。之所以会这样,是因为寻找领域或上下文边界才是DDD中最难,也是最需要创造力的地方。边界或有界上下文是DDD专门用于解决复杂性的有力武器,是DDD的核心内容。

DDD是专门解决复杂性的方法论。首先,当需求规模比较大时,需求内部之间可能会发生矛盾,有些矛盾隐藏得非常深,可能只能通过代码实践才会被发现,但是这种代价非常高。

使用DDD建模并不是为了将整个系统预先设计出来,而只是让一些有丰富领域知识和逻辑思考能力的人通过头脑风暴发现系统的复杂核心所在。

复杂性无法消除,问题空间的复杂性是天然存在的,一个大型系统肯定比小型系统复杂得多。人们理解复杂性有自己的一套分析方法,如分门别类,逐步、有层次地分解。DDD关注的重点就是如何将复杂的问题空间通过逻辑分析解析出来,从原来的混乱无序变得有条理、有层次,这样经过梳理的复杂性才是DDD需要的结果。由于分析结果变得有层次,相互隔离、松耦合,就能分派不同的团队专门处理各个问题的子域或有界上下文,分而治之。

DDD在一定程度上帮助解决了程序员的主要困惑。

DDD中的事件风暴(Event Storming)建模倡导将脑袋大开的产品经理和严谨求证的程序员召集在一起进行头脑风暴。大胆设想和小心求证在这里得到了融合,通过事件风暴会议,程序员能够更加理解业务领域知识,产品经理会发现自身的逻辑矛盾之处,通过反复迭代,创意开始变成可实施的产品。关键是,每个人对复杂性的认识逐渐一致,复杂性被专门隔离出来,可以先从容易的地方下手,逐步逼近复杂性。随着时间推移,每个参与者都会朝着目标更进一步,复杂性被肢解,由不同的团队专门负责不同的有界上下文或微服务,同时在敏捷实施过程中,不断调整人员。领域的边界划分不断演绎,只要发现复杂性凝聚的地方,就划定为有界上下文,割裂它与其他系统的关系,并派出精兵强将专门对付。

DDD是复杂问题的解决之道。DDD解决复杂性的方法并没有带来额外的复杂性。软件设计的思路不只是建数据表或实现CRUD的SQL编程,然后再放入一个微服务中,CRUD本身已经脱离了业务场景,已经是一种抽象思考 有可能因为抽象而漏掉了重要细节.

DDD解决问题的方式继承了多年的面向对象分析设计方法学,同时吸收了函数式编程的优点。面向对象和函数编程其实并不是矛盾不可共存的,面向对象更符合人类的思考习惯,可以帮助人类实现分门别类的大方向分析,划分边界,封装复杂性等,而函数编程更符合数学思维,适合计算机模型本身,在将人类分类的结果交由计算机运行过程中能发挥重大作用,同时也能避免人类自身没有计算机精确、没有计算机逻辑严密的缺陷。副作用通常是人类容易犯的错误,做一件事本来是为了某个目的,结果却有了另外一个不好的结果,而函数式编程则可以避免这种副作用,从而规避副作用带来的技术债务,提升软件质量。

DDD实施中最大的副作用是可变状态的管理。DDD聚合根代表一个有界上下文的复杂核心概念,其复杂性来自聚合根实体的状态是经常可变的,例如订单的状态从支付变为发货,这种变化决定了整个系统的成败——如果一个订单没有支付,但是商家发货了,这样是不合理的。DDD虽然通过边界划分和状态封装固定了复杂的可变状态,但是如果不结合函数式编程,这种可变状态产生的全局影响是很难消除的。如果一个新手程序员不小心改变了订单状态,这个订单就变得无从追查,损失的是客户利益,而采取事件溯源等方式,直接记录发生的领域事件,并不改变状态,所有需要订单当前状态的有界上下文自己通过遍历这些领域事件来合成当前状态,这样的状态既是实时的又是准确的,也是可以追溯的。

DDD解决了传统面向对象分析和设计的割裂状态。面向对象分析的结果会被设计细节干扰,导致严重偏离分析方向,DDD是一种“一竿子插到底”的方法,分析的结果必须经过设计细节验证。事件风暴倡导的是首先提取领域中发生的事件,从非常细节的动作入手来分析需求,而传统的面向对象分析方法则是主语名词法,首先寻找领域中有哪些实体名词,这种分析方法其实受到了ER数据模型的影响。主语名词法的严重问题是,如果人们无法发现主语名词,就只能替代以想象中的“上帝”了。

事件风暴从动词事件入手,虽然很琐碎,但是这些事件正是日后需要实现的功能激发的。事件离需求功能更接近,对领域事件进行分门别类,可以发现有界上下文和聚合。使用领域事件替代可变状态,可以实现有界上下文之间重要的状态传递,领域事件是就是DDD一竿子插到底的那根“竿子”。

事件风暴是在传统DDD基础上演变发展出来的,传统DDD也可以通过UML顺序图使用动词分析法,这点在Evan的书中已经得到体现。无论事件风暴还是UML,都是人类思想的表现形式,不必拘泥于表现形式,关键是要掌握DDD分析方法的核心:从细节动词入手发现有界上下文和聚合,以逻辑一致性为边界划分依据,对动作实现分门别类地划分。

DDD非常强调语言表达,可以说,DDD是一种关于自然语言符号分析的方法学,它倡导的统一语言、无所不在的语言,正是从语言分析入手去发现上下文语境的。同一个领域模型在不同上下文语境中是不同的,因此需要分别建模,例如客户这个模型在客户管理上下文和订单上下文中是不同的,客户管理上下文中客户无疑是主语,是主导者,而在订单上下文中,客户只是订单这个主语的附加定语或组成信息而已。

总之,DDD继承了传统面向对象分析设计方法,结合了函数式编程风格,同时照顾了ER数据模型的设计,可以说是过去这些主流方法学的集大成者,它通过划分边界、纲举目张、分而治之等分析方法直面分解复杂问题,而不是隐藏回避复杂问题。

DDD遵从单一职责、少即是多、大道至简等设计原则,吸收了各种新的分析方法和思想,不断努力降低技术债务,提升软件质量,提高软件的可维护性和可拓展性。

在基于DDD的论坛系统中,模块之间松耦合,特别是核心部分得到隔离,核心部分又通过聚合凝聚在一起,很多核心功能通过聚合功能优化即可,摆脱了对数据库的依赖,数据库表字段的增加和修改几乎完全避免了,也不会对原始数据进行各种转换。其中所有的设计都是通过Java代码实现的,轻量且容易改变,如果通过ER数据模型实现,对旧数据的转换就让人生畏,关键有时还需要转换回去,几万行数据中任何一行数据有问题,转换就会失败,即使转换成功,在新系统中不能正常读写时,又会涉及旧业务逻辑和新业务逻辑的比较。使用Java在内存中计算排序或做各种处理,包括业务流程的变化都不影响数据表结构,通过新增数据表结构来实现新业务数据的保存,不去修改原有结构,通过Java的聚合模型将新旧数据表结构凝聚在一起。

,