DDD(领域驱动设计) 核心概念浅析

news/2025/1/15 14:03:33/

文章目录

  • DDD(领域驱动设计) 核心概念浅析
    • 前言
    • 贫血模型
      • 什么是贫血模型
      • 贫血模型的优点
      • 贫血模型的缺点
    • 充血模型
      • 充血模型的优点
      • 充血模型的缺点
    • DP 概念
    • 抽象接口
    • 简单概念
      • 简单概念
      • 流程:
      • 实现
    • 统一语言和模型价值
      • DP 和 Entity 的区别
    • Aggregate(聚合)
    • 限界上下文
    • 防腐层(Anti-corruption layer)
      • 应用场景
      • 解决方案
      • 问题
    • 总结

DDD(领域驱动设计) 核心概念浅析

前言

大家好,这里是 Rocky 编程日记,喜欢后端架构中间件源码,该篇是对 DDD(领域驱动设计) 做了一个简短的概念梳理。文章分享出来,供大家学习交流,如若笔记中有不对的地方,那一定是当时我的理解还不够,希望你能及时提出。
在这里插入图片描述

贫血模型

什么是贫血模型

在日常项目中,我们也会把大部分的业务逻辑实现都写到 service 层里,而不是写在我们的实体类中。即实体类里面只包含了对象的属性以及属性的 get 、set 方法,不包括该对象的具体行为,业务逻辑都处于 service 层。

贫血模型的优点

将业务逻辑分离了出去,使得系统耦合度降低,对象只用作承载和传输暑假。

贫血模型的缺点

不符合面向对象编程 (OOP) 的思想,对象只有属性没有行为,没有生命,不是真正的对象。

业务逻辑分离到了 service 层,service 层会显得十分厚重。

充血模型

不仅包含了对象的属性,还包含了属性的职责,对象的行为,包括业务逻辑、数据持久化等操作。

充血模型的优点

面向对象,Business Logic符合单一职责,不像在贫血模型里面那样包含所有的业务逻辑太过沉重。

充血模型的缺点

对于如何划分业务逻辑,什么样的逻辑应该放在Domain Object中,什么样的业务逻辑应该放在Business Logic中比较含糊。

DP 概念

在 DDD 里,DP (Domain Primitive) 可以说是一切模型、方法、架构的基础。它是在特定领域、拥有精准定义、可以自我验证、拥有行为的对象。可以认为是领域的最小组成部分。

DP 三条原则

  1. 让隐性的概念显性化
  2. 让隐性的上下文显性化
  3. 封装多对象行为

思考: 在实际的项目中,如果你使用了充血模型,那么如何把握它的强弱程度?

依赖都是可以替换的,属于业务域核心逻辑之外的东西,你对他们是没有控制权的,即使这些外部依赖产生了变动,也能将自身系统产生的变化,控制在最小范围内。
由外部系统的依赖变动,导致的内部系统的改造程度,我们可以理解为一个系统的可维护性。

抽象接口

抽象接口本质是一种中间协议,依赖方和被依赖方都只要对该协议负责,接口将软件分层隔离,在这种隔离下任何一方的变动都将被控制在当前范围内。

M个业务 * N个业务 -> M个业务 + N个业务
由内部逻辑的变化所导致的内部系统的改造程序,我们可以狭义地理解为系统的 可扩展性。

思考:发奖的逻辑如果改动,难道还要修改注册逻辑么?

简单概念

简单概念

● DP:抽象并封装自检和一些隐性属性的计算逻辑,且这些属性是无状态的
● Entity:抽象并封装单对象有状态的逻辑
● Domain Service:抽象并封装多对象的有状态逻辑
● Repository:抽象并封装外部数据访问逻辑。

流程:

  1. 首先对需要处理的业务问题进行总览。
  2. 然后领域对象 (Entity) 进行划分,明确每个领域对象的包含的信息和职责边界。并进行跨对象,多对象的逻辑组织(Domain Service)。
  3. 接着在上层应用中根据业务描述去编排 Entity 和 Domain Service。
  4. 最后再做一些下水道工作,去对下层的数据访问、RPC调用去做一些具体

实现

DDD语境传统语境
含义ValueObjectViewObject / ValueObject
作用领域基础类型用于展示的数据

统一语言和模型价值

财务人眼中技术人眼中
含义资产=负债+所有者权益借钱? 存钱?贷款?

为了建设有价值的模型,我们需要在形成UL的基础上,消化知识,并向模型中提炼知识。

DP 和 Entity 的区别

DP(VO)Entity
是否充血
有无状态

举例:有无状态的判定即 “程序是否需要追踪该对象的变化事件”,具体来说就是 假如体育场的很多座位,观众通过预定程序买了票,每张票上都对应一个座位号,这种场景下,座位就是有状态的,它是 Entity , 程序需要关注该对象的变化事件,比如通过唯一 ID 来追踪该对象,关注它的预定状态,价格,位置等属性。另一种场景下,假如观众通过预定程序买了票,进场只要有空座位就可以随便坐,这时候,座位就是无状态的, 它是 DP ,程序不需要对每个座位对象加以追踪,只需要关注总数即可。这也是 DP 和 Entity 的异同之处。

为了建立有价值的模型, 在确认了 UL 之后消化领域知识,并向无状态的 DP 和有状态的 Entity 中提炼知识。

在复杂的系统中,对一个对象进行修改,可能会涉及到大量其他关联对象的状态,如何使这些关联的对象始终保持一致,是一个比较复杂的话题。

Aggregate(聚合)

聚合是对存在引用关系的一组对象的封装,它的目的就是屏蔽掉内部对象之间复杂的关联关系,只对外暴露统一接口,关于聚合,我们需要关注它的两个属性,根对象 (root) 边界 (Boundary)

根对象:是整个聚合中唯一能够被外部引用的对象,也就是说 聚合所暴露的接口只允许操作根对象,根对象是一个 Entity, 因为每个聚合都需要 ID 和状态来区分其他聚合,所以这里也是通过根对象的 ID 来作为整个聚合的 ID。

边界: 简单来说,聚合的边界就是你判断哪些对象可以被放入当前聚合的条件。

限界上下文

本质是为了解决复杂系统的领域分治问题,这并不仅仅是 DDD 这种架构方式需要面临和处理的问题,其他任何架构方式都需要处理类似问题,领域分治最清晰的方式就是通过拆分成微服务,但拆分成微服务本身也存在边界问题,而且将会增加通信的复杂度,

其次,有些领域能力本身就适合作为一个集合,由一个系统来提供,不适合按照每种能力拆分成微服务,所以在一个系统内,如何进行领域分治,也是一个有价值的话题。

防腐层(Anti-corruption layer)

防腐层(Anti-Corruption Layer)模式,是一种在不同语义的子系统间构建的一层功能,对子系统间的请求进行翻译适配,从而确保应用设计不受外部依赖的系统的限制。

应用场景

许多应用依赖于外部系统提供的数据或者功能。当直接使用外部系统的API、数据结构时,自身就存在因使用外部系统,而被外部系统的质量问题影响,从而“腐化”本身设计的问题。比如,当一个遗留应用需要移植到新系统时,可能仍需使用现存的遗留资源,新的特性需要调用遗留系统。这种场景在系统迁移过程中尤其普遍。

解决方案

在应用自身与外部之间,构筑专门的一层组件或者服务,对两个系统进行通讯转换和语义隔离。这层组件或者服务,称为 防腐层

问题

  • 防腐层可能增加两个系统间的通讯延迟;
  • 防腐层增加了额外的服务,需要管理和维护;
  • 如果防腐层是系统迁移战略的一部分,则需要考虑防腐层是否是永久的,是否在遗留系统功能完全迁移完成后将其移除。

总结

大家好,这里是 Rocky 编程日记,喜欢后端架构中间件源码,该篇是对 DDD(领域驱动设计) 做了一个简短的概念梳理。后面也会陆续分享更多有关于 DDD(领域驱动设计) 的知识,喜欢的小伙伴们可以三连支持一下噢~,同时也可以评论区留下你宝贵的意见噢 ~


http://www.ppmy.cn/news/559875.html

相关文章

通过signed int 再提补码

通过signed int 再提补码 有符号int (signed int) 的取值范围 [-2^31, 2^31 - 1 ] 理解: 理解上记住一点:负数的话,用的是补码 1000 0000 0000 0000 0000 0000 0000 0000 # 表述 aint 一般情况是4字节,32位 我们看 表述a 的补数 …

Baumer工业相机堡盟工业相机如何通过BGAPISDK循环查找相机序列(C++)

Baumer工业相机堡盟工业相机如何通过BGAPISDK循环查找相机序列(C) Baumer工业相机Baumer工业相机BGAPISDK和循环查找相机序列的技术背景Baumer工业相机通过BGAPISDK循环查找相机序列功能1.引用合适的类文件2.通过BGAPISDK循环查找相机序列功能 Baumer工业…

Spring Cloud 之注册中心 Eureka 精讲

🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…

2017电脑性能测试软件,哪个比较权威呢 电脑跑分软件排行榜2017年

电脑跑分软件排行榜2017年: 电脑跑分软件,可以对CPU、显卡、硬盘、内存等等各个配件进行测试,并把测试结果以跑分形式计算出来。这类工具也很多,不过可以一个一个拿测试,综合比较结果,对整机进行评估测试。…

计算机游戏软件视频,电脑录制游戏视频软件哪个好,电脑游戏录制软件排行

电脑游戏录制软件有哪些 分享一:专业游戏录屏软件 这里为大家分享的第一款是专业游戏录屏软件,即通过专业的“嗨格式录屏大师”录屏游戏。在分享录屏游戏的方法之前,先为大家介绍一下这款软件。嗨格式录屏大师是一款能够同时适用于Windows和M…

电脑c语言小游戏,C语言中的一个小游戏的排行榜系统...

我把你的代码改了一下,我已经运行过了,你看看 #include #include #include int play(int suiji); void paihangbang(struct p a[100],int r); struct p {char name[20]; int cishu; }chengji[100]; void main() {int i,suiji, xuanze; i=0; /*i=猜测了多少次,suiji=产生的随机…

ElasticSearch-使用IK分词器进行分词

使用KIbana测试IK分词器 打开开发工具台 ik_smart 最少分词器 分词结果比较少 GET _analyze{"analyzer": "ik_smart","text": "中国共产党"}ik_max_word 颗粒度最细分词器 分词结果比较多,组成各种结果,穷尽词库的可能&#xff01…

闭门造轮(LVGL_2)

例程1_// 组件(widgets): 标签(label)的用法 static void label_event_cb(lv_event_t * e) {lv_obj_t * obj lv_event_get_target(e); // 获取触发事件的部件(对象)lv_event_code_t code lv_event_get_code(e); // 获取当前部件(对象)触发的事件代码sw…