Golang学习

领域驱动设计 学习笔记

2020-07-24  本文已影响0人  半亩房顶

前言

初次接触领域驱动设计,总结了下公司某大佬的分享,摘选部分,记录如下:

业务架构设计演进

事务脚本 + 贫血模型


实现业务逻辑是最后一步,并且业务逻辑代码的开发是过程式的,这种开发方式在行业里面有一个特定的名称-事务脚本(过程式的),它有以下几个特点:

模型中只有数据,没有行为,这时候模型只是数据库表在代码中的映射,在软件设计里面有一个专有名词描述这种现象-贫血模型

service + 贫血模型


随着需求越发复杂,我们的代码中出现了很多复用、职责不单一等坏味道,所以我们逐步的需要用到一下几个技能:

这套开发流程,我们称它为“service + 贫血模型”,它有如下几点优势:

Service的设计有一些原则需要把控

service + 充血模型

随着需求更加的复杂,业务体量越来越大时,我们需要如此改进:



(1)事务控制不要放在领域模型的对象中实现,可以放在facade中完成。
(2)领域模型对象中只保留该模型驱动的一般方法,对于业务特征明显的特异场景方法调用放在facade中完成。

充血模型和领域驱动设计

而领域驱动设计,也就是DDD,是建立在充血模型之上的,即:

领取驱动设计中的领域模型都是充血模型

要理解领域驱动设计,就一定要知道什么是”领域“:

领域与具体开发技术无关。领域是你的软件系统要解决的实际问题相关的所有东西的集合。 比如跟谁学好课系统,那么如何创建课程、如何决定优惠规则、如何安排作业、如何管理学生、如何分析销售数据等等,这直接与业务相关的所有东西都归属于“领域”。

进而就是领域驱动设计:

领域驱动设计就是说你得先把“领域”中涉及到的数据、流程、商业规则等都弄明白了,然后以面向对象的观点为其建立一个模型(即领域模型,也就是上面的充血模型),再使用合适的软件技术去实现这个模型。 是你为领域所建立的那个模型,决定了你将用什么技术、采用什么架构、基于什么平台来实现这个软件系统。 所以说是领域”驱动“系统设计。技术在这个过程中是“被动的”,是被“选来”实现“领域模型”的,对于项目的成败,技术不是决定性因素,领域模型是否符合事物的本质才是关键。 基于对事物错误的理解而创建的领域模型,将导致开发出来的软件系统没有长久的生命力,随着时间的推移,很快就会被抛弃,因为它不能解决真正的解决现实问题。

在编码实现业务功能时,通常用2种工作流程:
1、自底向上:先设计数据模型,比如关系型数据库的表结构,再实现业务逻辑。我在与不同的程序员结对编程的时候,总会是听到这么一句话:“让我先把数据库表的字段设计出来吧”。这种方式将关注点优先放在了技术性的数据模型上,而不是代表业务的领域模型,是DDD之反。

2、自顶向下:拿到一个业务需求,先与客户方确定好请求数据格式,再实现Controller和ApplicationService,然后实现领域模型(此时的领域模型通常已经被识别出来),最后实现持久化。

一些概念

实体

DDD规定,具有唯一标示属性的对象,叫做实体

值对象

当一个对象用于对事务进行描述而没有唯一标识时,它被称作值对象(Value Object)。

聚合 和 聚合根

领域服务

业务逻辑应该优先写在聚合内,当业务逻辑不属于一个聚合时,可以写在领域服务中,比如有些业务逻辑需要协调多个聚合才能完成,这种可以在Service中实现。

以上整个活动在DDD中称为领域建模,在整个过程中我们不需要考虑任何技术相关的东西,都是在分析业务逻辑,并按照DDD的指导思想进行代码实现。

仓库

当Domain层的代码都编写完之后,该仓库登场了,它负责持久化聚合到存储中,也负责在需要的时候从存储中加载数据并重建整个聚合,在这个阶段我们才需要关注技术细节,应该选择什么类型的数据库,表结构应该怎么设计,这个步骤是服务领域建模的。

Repository 和 DAO 有什么区别呢?从技术上讲,Repository和DAO所扮演的角色相似,不过DAO的设计初衷只是对数据库的一层很薄的封装,而Repository是更偏向于领域模型。另外,在所有的领域对象中,只有聚合根才“配得上”拥有Repository,而DAO没有这种约束,你可以一张数据库表一个DAO。

引用

后端开发实践系列——领域驱动设计(DDD)编码实践
架构蓝图--软件架构 "4+1" 视图模型
领域模型、贫血模型、充血模型概念总结
复杂业务代码要怎么写
领域驱动设计(DDD)编码实践

引申学习


欢迎大家关注我的公众号


半亩房顶
上一篇 下一篇

猜你喜欢

热点阅读