DDD领域驱动设计
1.什么是DDD
1.DDD(Domain-driven-design,模型驱动设计)是一个很好的应用于微服务架构的方法论
2.在项目的全生命周期内,所有岗位的人员都基于对业务的相同的理解来展开工作。所有人员站在用户角度、业务角度去思考问题,而不是从技术的角度去思考问题
2.领域
1.领域(Domain):一个组织要去做的各种事情。子领域也就是各种事情里面的一件一件事情
2.领域的划分
- 核心域:项目的核心问题,和组织业务紧密相关
- 支撑域:解决项目的非核心问题,也具有组织特性,但不具备通用性。
- 通用域:解决通用问题,没有组织特性
刚开始听杨中科对着ppt念,脑袋一懵….什么玩意儿啊?😭😭😭😭😭
接着对比老杨说的案例我另外套娃自己想一个好了,就拿我目前所入职的公司yes数字,亲切的我叫他yes。
3.领域划分的理解
子领域和核心域:那么组织就是yes,yes做的一些事情就是领域。比如yes 做一些TO G项目,这个是yes的核心业务,因为yes从我看来就是个软件公司,软件公司不就是做软件的,做软件就是一个领域,并且还是核心领域,也就是核心域!再来看看做软件能不能拆出来成子领域呢?做软件做啥软件?web,app这么多,比如年前制作的祝东村微信小程序,那么也就可以拆开一个微信小程序领域,别人问yes能做小程序么?可以做那么理解一下做小程序是不是就是个领域,它是做软件的下面的子领域。
支撑域:再来说说支撑域,从字面意思上,解决项目的非核心问题。什么是非核心问题呢,就是yes可做可不做的事情,好比祝东村要上一下机器硬件部分,yes是个软件公司,他是做软件的,怎么一下子倒卖硬件去了,还有前段时间yes一下子又要做什么VR,有点像是分支,TO G的WEB+小程序是主分支,什么倒卖硬件,搞VR是分支,能搞搞搞不了直接把分支remove,对于yes来说即使没有靠着核心的电视端还有TOG的项目也能保证主要稳定来源。
通用域:最后的通用域这个好理解,yes是个公司,阿里巴巴也是个公司,虽然不是一个级别的,但是只要是公司都有一个通用的领域,好比人事领域,是个公司你得招人,财务领域,是个公司你都得有财务吧,这个也就是通用领域。
可能说一堆看的字多我觉得还是画成图比较好理解
4.画图示意
5.领域的不同分类决定了公司的研发重点,
3.领域模型
1.对于领域内的对象进行建模,从而抽象出来模型。
2.项目开始应该创建领域模型,而不是说考虑如何设计数据库和代码。使用领域模型,我们可以一直用业务语言去描述和构建系统,而不是用技术层面的语言去想象。
假如现在要设计一个电商项目,那么电商项目的领域就可以分为用户个人信息领域,购物车领域,商品领域,订单领域,先设计这些领域,再去建立领域模型好比用户表,购物车表,商品表到数据库。
4.通用语言
理论上意思是:一个拥有确切含义的,没有二义性的语言。
有点像是你和产品对一个具体业务的不用理解,比如一个电商项目,你理解的用户是买商品的用户,产品理解的是后台的管理员用户,牛头不对马嘴,那么在探讨业务需求的时候就会消耗一些不必要的时间,这个时候就需要定一个通用语言。
5.界限上下文
通用语言离不开特定的语义环境,只有确定了通用语言所在的边界,才能没有歧义的描述一个业务对象。
好比就是前面说的通用语言的举例,都是用户这个名词,在后台管理系统,用户就是管理员。在电商购物车里头,那么这个用户就是买家。那么这个后台管理系统和电商项目就是界限上下文,在确定了这个通用语言一定是存在在界限上下文中的,也就是上面说的语义环境。
6.实体(Entity)
可以参考EF Core中的实体类,它可以对数据库表的映射,实体一般都有一个标识符,这个标识符就是在数据库表当中的主键id,无论一个实体类如何变化,它的主键id是不可能变化的,并且我们也可以通过它的主键id来定位到这个实体。
7.值对象(Value Object)
1.值对象是依附于实体存在的,是没有标识符的对象,也可以又多个属性,比如商家的地理位置,衣服的RGB颜色
2.定义为值对象和实体的区别:体现整体关系
8.聚合和聚合根
搞清楚聚合首先得知道聚合是啥意思,聚合也就是高内聚,低耦合简称聚合,搞清楚聚合那么我们也应当先弄清楚什么是高内聚,低耦合
8.1 低耦合
耦合也就是元素和元素之间的连接、感知、依赖度量,这里所说的元素可以是功能,对象,系统,子系统。模块。
比如现在有方法A和方法B
我们在A元素去调用B元素,当B元素有问题或者不错在了,A元素就不能正常工作了,那么说明元素A和元素B有高耦合,也就是A太过于依赖B了
那么耦合会带来什么问题呢?
当元素B变更或者不存在,都将影响元素A正常运行,影响系统的可维护性和易变更性。同时元素A只能运行在元素B中,大大降低了A的可复用性,也是因为耦合的种种弊端我们才需要在软件设计上追求低耦合。
低耦合应该如何做?
(1)元素A不能过分依赖元素B
(2)合理的职责划分:让系统中的对象各司其职,不仅是提高内聚的要求,也可以有效的降低耦合
(3)使用接口而不是继承,比如一个父类有100个子类,删除了父类那么这100个子类运用到了父类的属性方法就都要修改,依赖性就特别强,假设接口删了,实现类只需要删除一下继承的地方大大降低了耦合
8.2 高内聚
高内聚是另外一个评判软件设计质量的标准。内聚更为专业的说法叫做功能内聚,是对系统中元素职责的相关性和集中度的量度。如果元素有高度的相关职责,除了这些职责在没有其他的工作,那么该元素就有高内聚。
比如我们的产品 他只负责调研项目需求不会去管开发 测试,他只关心自己的职责
再简单的说: 高内聚、低耦合讲的是程序单位协作的问题, 你可以这样理解,一个企业的管理, 最理想的情况就是各个部门各司其职,井然有序,互不干涉, 但是需要沟通交流的时候呢, 各个部门都可以找到接口人专门负责部门沟通以及对外沟通。 在软件里呢, 就是说各个模块要智能明确, 一个功能尽量由一个模块实现, 同样,一个模块最好只实行一个功能。这个是所谓的“内聚”; 模块与模块之间、系统与系统之间的交互,是不可避免的, 但是我们要尽量减少由于交互引起的单个模块无法独立使用或者无法移植的情况发生, 尽可能多的单独提供接口用于对外操作, 这个就是所谓的“低耦合”。 但是实际的设计开发过程中,总会发生这样那样的问题与情况, 真正做到高内聚、低耦合是很难的,很多时候未必一定要这样, 更多的时候“最适合”的才是最好的, 不过,理解思想,审时度势地使用, 融会贯通,灵活运用,才是设计的王道
8.3 聚合
1.现在再来说说聚合,聚合的目的就是高内聚,低耦合。有关系的实体紧密协作,关系弱的实体被隔离
2.关系紧密的实体放到聚合中,每个聚合中有个实体作为聚合根,所有对于聚合内的访问通过聚合根来进行,外部只能持有对聚合根的引用。
3.聚合根不仅仅是实体,还是所在聚合的管理者
8.3 聚合根
假设有个订单实体,它里面包含了订单商品,订单明细一堆多,一对一的,我们获取订单商品就需要通过订单实体去拿订单商品,此时聚合根也就是订单实体类。此时抽象化一些这个订单,商品,明细整合成了一个聚合。
9.领域服务和应用服务
1.聚合中的实体是没有业务逻辑代码,只有对象的创建,对象的初始化,状态管理等等个体相关的代码。
2.对于聚合内的业务逻辑代码,我们编写领域服务(Domain Service),而对于跨聚合协作的,或者和外部系统协作的逻辑,我们编写应用服务(Application Service)
3.应用服务协调多个领域服务、外部系统服务
10.仓储和工作单元
1.仓储(Repository) 负责按照要求从数据库中读取数据以及把领域服务修改的数据保存回数据库
2.聚合内的数据操作关系是关系非常紧密的,我们要保证事务的强一致性,而聚合间的协作式关系不紧密的,因此我们只要保证事务的最终一致性即可
3.聚合内的若干相关联的操作组成一个工作单元,这些工作单元要么全部成功要么全部失败
11 领域事件(Domain Events)和集成事件(Integration Events)
1.DDD中的事件分为领域事件和集成时间
2.领域事件:在同一个微服务内的聚合之间的事件传递。使用进程内的通信机制完成。
3.集成事件:跨微服务的事件传递。使用事件总线(EventBus)实现
12 贫血模型和充血模型
1.贫血模型:一个类中至于属性或者成员变量,没有方法
使用简单 可以直接用efcore的dbfirst
2.充血模型:一个类中既有属性,成员变量,也有方法
使用难度大,可以适量的减轻业务代码
- Title: DDD领域驱动设计
- Author: faith team
- Created at: 2023-09-06 11:21:05
- Updated at: 2025-11-29 09:01:08
- Link: https://redefine.ohevan.com/2023/09/06/20230906DDD/
- License: This work is licensed under CC BY-NC-SA 4.0.
