DDD领域模型

领域驱动设计(DDD)是一种架构方法论,用于拆解和组织复杂业务。它强调通过识别领域、子域和核心域来确定业务边界,并建立领域模型以支持软件扩展。文章介绍了DDD的关键概念,如子域、通用语言、限界上下文和领域模型的不同类型,以及如何通过事件驱动和领域服务来处理业务逻辑。同时,文章讨论了不同类型的领域模型(失血、贫血和充血模型)及其优缺点,并指出在代码落地时需谨慎处理复杂性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思维导图

  

一 认识领域模型

Domain Driven Design(领域驱动设计, DDD),不是一种架构,而是一种架构方法论,是一种拆解业务、划分业务、确定业务边界的方法,是一种领域设计思想。

DDD(领域驱动设计)实际上是一套软件架构设计的方法论,我们可以在此之上更好的理解业务。并且我们可以根据这套方法论进行架构风格填充,包括微服务架构,面向服务架构,REST风格架构以及六边形架构等等。

解决的问题:软件开发完成后,因需求的变更导致软件不得不增加新的功能,软件越来越冗余,导致最后不得不重构,领域驱动设计能分析好领域相关的业务逻辑,确定好边界,确定同一沟通预言,让软件通过领域模型设计后,更易于扩展。

使用场景和要求:

        1 在一开始就使用领域驱动,已经开发的是不能使用领域驱动的。

        2 要开发的软件非常的复杂,才需要使用到领域驱动

        3 对于项目中架构师的技术要求非常高。并且,架构师不仅仅应该对于各个组件,框架了如指掌。更需要对于业务有非常强的掌控力。、

        4 整个项目中,各个角色都应该非常专业,有相当的专业度。

核心思想:领域驱动的核心思想就是将问题慢慢细化,同时找出最核心的问题点,倾斜资源保证核心资源不出问题,同时也可以通过领域的细分,去慢慢的缩小我们的子域所要解决的问题,并且构建合适的领域模型。

个人理解:我们用软件去解决一些问题,首先要确定软件的边界,确定软件解决的问题,然后围绕这个根本问题(领域),去划分成多个子问题(子领域),分治的方法解决复杂软件的设计问题,划分之后通过一些方法,对子领域进行分析,画出领域模型,基于这种思想,为了达到这种目的,领域驱动设计会有很多其他具体步骤和划分实体等分类,并且有集中领域模型应对不同的情况,牵扯到模式,还有如何开会去讨论领域模型,总之为了解决复杂领域的软件设计,领域驱动不只是空的方法论,里面有很多小的方法来支撑他的各种操作。

二 领域模型关键词解释

领域

领域其实就是我们的范围,而范围实际上就是我们的边界,我们做什么,做到什么程度,最低多少 ,最高多少。

领域其实就是我们的范围,而范围实际上就是我们的边界,我们做什么,做到什么程度,最低多少 ,最高多少。

比如 电商 就是一个领域  ,金融是一个领域,教育是一个领域,你要确定你做的软件产品,具体的领域边界,分析涉及到的数据,业务规则,流程,然后通过面向对象的方式建立一个模型,再选择合适的技术实现。

子域

领域太过于复杂,业务太过于分散,这个时候我们做一个拆分,把领域划分成子域,比如电商系统很复杂,将他拆分成比如一个个的模块,订单,商品,库存,甚至我们的模块还能进行细分,比如库存,可以分为本地库,异地库,三方托管库。划分子域 1 是分治,2是可以对子域进行分析,重要的子域加资源。

核心域(子域)

业务核心,核心的竞争力,因为企业愿景不同,领域愿景也不同,核心域也不同,说白了,就是你们项目最初立项的目的是什么,目标是什么。为什么要做这个项目。核心域的范围并不一定是一次就能确认的,可能需要迭代很多次,每一次都有可能扩大或缩小。

通用域(子域)

整个领域都能够用到的子域,比如我们的认证,权限等等相关的模块,这就是我们的通用域。

支撑域(子域)

支撑域实际上就是不包含核心竞争力的功能,也不包含通用的功能,但是又是必须的支撑。

通用语言

必须要有一个东西能够让我们的团队人员交流起来有一个标准。并且他还需要能够正确的,简单的,清晰的表达业务。让我们的技术专家,业务人员,产品,测试,架构都能够达成共识,并且协同合作。这个叫做通用语言,类似需求文档里的词语解释,就是让大家能在同一维度进行高效的交流沟通。

限界上下文

限界和上下文。限界就是领域的边界,也就是范围,而上下文则是语义环境。通过领域的限界上下文,我们就可以在统一的领域边界内用统一的语言进行交流。

领域模型

领域模型是对领域内的概念类或现实世界中对象的可视化表示,领域模型是用来描述业务对象之间的引用关系。

  • 业务角色,业务角色表示的是一个角色承担的一系列责任。比如收银员,他的责任是计算商品价格,收钱,找零,甚至退换货。
  • 业务实体,业务实体表示的是其实你使用或者可交付的工件,资源,事件。比如电商项目中的商品。你需要给卖家打印的发票。
  • 业务用例,实际上业务用例显示的是协作角色与业务实体之间如何执行工作流程,也就是我们的业务链路

实体(Entity)

正常的实体对象,有唯一键标识,就算所有字段内容一样也不是一个,例如学生,id,姓名,年龄,就算姓名年龄一样,也不是一个。

值对象(Value Object)

没有唯一性标识,例如 学生实体上有一个地址,这个地址是一个对象,里面字段为,省,市,街道,详细地址,这个地址信息对象就是值对象。

聚合聚合根 

平常我们有的实体比较复杂,为了满足业务,有可能会弄出一个非常复杂的实体,里面包含很多实体,跟这个类似,这里的聚合是指同一生命周期,同一业务域的实体聚合成一个聚合根,也就是最外面的实体,并且这个实体管理者里面的所有实体,外面只能通过聚合根进行任何和请求,聚合根再对里面进行操作,这里我感觉就是高内聚,聚合根不易过大。

领域服务

业务逻辑写那个实体中都不合适就写到领域服务中

注意

  • 不能在领域服务里写太多的业务逻辑
  • 不能在领域服务里调用dao和仓储
  • 领域服务视为实体的一种补充,里面的属性和逻辑也和实体一样,不能是基础类型得是含有业务含义的值对象
  • ·领域服务之间可以进行调用,最好是保持父域的领域服务调用子域的领域服务,不允许跨越上下文进行调用

和实体一样,如果有不相关的领域服务的调用,或者有跨上下文的情况,使用领域事件进行解耦

领域事件

事件驱动,有一些代码逻辑,例如下单,后面有很多操作,一般我们一个下单方法里会包含好几个子方法,并且带有if,时间长了会非常冗余,并且方法越来越大,事件驱动就是,当下单之后发一个事件(mq)如果需要做一些操作,多个端接收这个消息事件,然后做自己的操作就行,扩展的话就多一个接收方,对之前代码无侵入修改。

领域专家所关心的发生在领域中的一些事件。
将领域中所发生的活动建模成一系列的离散事件。每个事件都用领域对象来表示...领域事件是领域模型的组成部分,表示领域中所发生的事情。

仓储与工厂

事件风暴

二  领域模型分类

1 失血模型

失血模型实际上就是我们的对象模型中只包含我们的get,set方法,像我们的排序,分页等等任何的通用性操作都不会包含在我们的对象中。

优点

  • 领域对象结构简单

缺点

  • 肿胀的业务服务代码逻辑,难于理解和维护
  • 无法良好的应对复杂业务逻辑和场景

2 贫血模型

贫血模型实际上就是在失血模型的基础上增加了不依赖于持久化的原子领域逻辑。比如我们经常会使用到的排序,分页等等操作。

优点

  • 层次结构清楚,各层之间单向依赖
  • 对于只有少量业务逻辑的应用来说,使用起来非常自然
  • 开发迅速,易于理解

缺点

  • 无法良好的应对非常复杂逻辑和场景

充血模型:

充血模型中实际上我们的领域对象不仅仅包含了我们的非持久化逻辑,甚至还包含了我们的持久化逻辑.那么我们的业务逻辑层在充血模型里还需不需要呢?依然是需要的,但是我们的充血模型的业务层实际上只会做一些整合的操作以及封装事务,其他的操作都会在我们的领域对象中完成

优点

  • 更加符合OO的原则
  • Business Logic层很薄,符合单一职责,不像在贫血模型里面那样包含所有的业务逻辑太过沉重,只充当事务管理以及整合的角色,不和DAO打交道。

缺点

  • 职责不好进行划分,我们的业务逻辑到底是划分到我们的哪一个层级呢?是领域对象还是业务属性呢?哪些划分到领域对象呢?而且持久化的内容都放在我们的领域对象里.所以我们在写业务的时候会深入到领域对象去,这对于开发者的水平要求很高,变相的增加了企业的成本.
  • 其次,由于充血模型包含了太多的操作,你实例化的时候也会有很大的麻烦,拿到了很多你不需要的关联模型.

四 设计与落地

我看了下技术落地的代码,结论就是 非常简单的逻辑会搞得非常复杂,结论就是不建议代码落地。

### 领域驱动设计 (DDD) 模型介绍 领域驱动设计(Domain-Driven Design, DDD)是一种专注于解决复杂业务问题的软件开发方法论。其核心在于将系统的构建围绕着业务领域展开,而非单纯的技术实现主导[^1]。DDD 提倡通过统一语言、业务抽象、领域划分和领域建模等方式降低系统复杂度,并帮助开发者更好地理解和表达复杂的业务需求。 #### 核心理念 DDD设计理念可以分为以下几个方面: - **统一语言**:团队成员之间建立一种共同的语言体系,用于描述业务概念和技术实现之间的映射关系。 - **限界上下文(Bounded Contexts)**:明确不同业务领域的边界范围,防止因跨领域混淆而导致的设计混乱。 - **聚合根(Aggregate Root)**:作为一组对象的整体表示形式,在事务一致性上起到重要作用。 - **领域事件(Domain Events)**:记录并传播发生在特定时间点上的重要变化,支持异步通信机制以增强灵活性[^3]。 --- ### 应用场景分析 DDD 特别适合应用于具有高度复杂性和动态性的业务环境之中,尤其是在以下几种典型情况下显得尤为重要: 1. **复杂业务逻辑管理** 当面对多变且相互关联紧密的企业运营流程时,采用传统方式难以有效维护代码质量与功能扩展性;而借助于 DDD 方法,则可以通过清晰界定各子域职责来简化整体架构结构[^2]。 2. **分布式系统建设** 对于需要跨越多个独立部署单元协同工作的大型项目而言,利用基于事件驱动的消息传递模式能够显著提升组件间松散程度的同时保持高效的数据同步性能。 3. **微服务架构下的模块划分** 微服务体系提倡按照具体职能拆分应用程序为若干小型自治服务单位。在此过程中运用 DDD 思想可以帮助确定合理的分割依据——即从业务角度出发识别出最自然的功能分区位置。 ```python class OrderService: def place_order(self, customer_id, product_ids): order = self.create_order(customer_id, product_ids) payment_result = PaymentGateway.charge(order.total_amount) if not payment_result.successful: raise Exception("Payment failed") inventory_service.reserve_stock(product_ids) event_bus.publish(OrderPlacedEvent(order.id)) def create_order(self, customer_id, product_ids): # 创建订单的具体逻辑... pass ``` 上述示例展示了如何在一个典型的电子商务平台中使用 DDD 原则组织代码。`OrderService` 属于应用层,负责协调其他层次的操作顺序;同时触发了一个 `OrderPlacedEvent` 来通知相关方该动作已完成。 --- ### 结语 综上所述,领域驱动设计不仅提供了理论框架去指导我们怎样分解庞大的商业难题成易于管理和理解的小部分,而且也给出了实际可行的技术工具集以便落地这些想法。对于那些追求长期可持续发展的企业级解决方案来说,采纳这样的策略无疑是非常有价值的。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值