当前位置: 首页 > news >正文

DDD是什么?电商系统举例

一、DDD的基本概念

领域驱动设计(Domain-Driven Design,简称DDD)是由Eric Evans提出的一种软件开发方法论,旨在应对复杂业务系统的设计和实现。它的核心思想是将软件的设计与业务领域紧密结合,通过深入理解业务需求,构建一个反映真实业务逻辑的模型,并用代码清晰地表达出来。

在传统的开发模式中,我们常常以技术为中心,先设计数据库表结构或API接口,再围绕这些技术组件填充业务逻辑。而DDD则反其道而行之,它强调**领域(Domain)**是软件的核心,技术只是实现领域的工具。换句话说,DDD的目标是通过代码和架构让业务逻辑成为系统的“主角”。

DDD的核心原则
  1. 聚焦领域:软件的核心是解决业务问题,而不是技术本身。
  2. 统一语言(Ubiquitous Language):开发团队和领域专家使用一致的术语,确保沟通无歧义。
  3. 模型驱动设计:通过领域模型将业务概念抽象为对象、关系和行为,并映射到代码中。
  4. 分层架构:将系统划分为多个层次,隔离关注点,提升可维护性。
  5. 限界上下文(Bounded Context):为不同的业务子域定义清晰的边界,避免概念混淆。
DDD的两个阶段
  • 战略设计:关注宏观层面,比如划分限界上下文、定义子域、建立上下文映射。
  • 战术设计:关注微观层面,比如如何设计实体(Entity)、值对象(Value Object)、聚合(Aggregate)、领域服务(Domain Service)等。

为什么需要DDD?

假设你正在开发一个电商系统,里面涉及商品、订单、库存、支付等功能。如果没有清晰的领域划分,可能出现以下问题:

  • 商品的“价格”在不同模块中有不同定义,导致逻辑混乱。
  • 订单和库存的耦合过于紧密,改动一处牵动全身。
  • 随着业务扩展,代码变得难以维护,新增功能需要改动大量现有代码。

DDD通过领域模型和限界上下文解决了这些问题。它鼓励你先理解业务的全貌,再通过分层和模块化设计,让每个部分的职责清晰,降低耦合性。

DDD的分层架构

DDD通常采用以下四层架构:

  1. 表现层(Presentation Layer):处理用户交互,比如API接口、Web页面。
  2. 应用层(Application Layer):协调业务用例,调用领域层完成具体操作,不包含业务逻辑。
  3. 领域层(Domain Layer):核心层,包含业务逻辑、实体、聚合等。
  4. 基础设施层(Infrastructure Layer):提供技术支持,比如数据库访问、消息队列、外部服务调用。

二、在Spring Cloud Alibaba微服务架构中应用DDD

假设我们现在要设计一个基于Spring Cloud Alibaba的电商微服务系统,包含商品管理、订单管理、库存管理和支付管理等模块。我们可以用DDD来规划架构和文件结构。

系统背景

  • 技术栈:Spring Cloud Alibaba(Nacos配置/注册中心、Sentinel限流、Seata分布式事务等)。
  • 业务需求:用户可以浏览商品、下订单,系统需要实时更新库存并处理支付。
  • 微服务划分:按业务能力拆分为商品服务、订单服务、库存服务和支付服务。

DDD在微服务中的应用

  1. 限界上下文:每个微服务对应一个限界上下文,例如订单服务关注订单的创建和状态管理,库存服务关注库存的分配和扣减。
  2. 聚合根:每个限界上下文有一个核心实体作为聚合根,比如订单服务中的“Order”、库存服务中的“Stock”。
  3. 领域事件:通过事件驱动(比如Spring Cloud Stream + RocketMQ)实现服务间协作,例如订单创建后发布“OrderCreatedEvent”通知库存服务扣减。

三、典型的DDD文件框架(电商系统)

以下是一个基于Spring Cloud Alibaba的电商微服务系统的DDD文件框架。我们以订单服务(Order Service)为例,展示其目录结构。其他服务(如商品服务、库存服务)可以参照类似结构。

order-service/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── ecommerce/
│   │   │           └── order/
│   │   │               ├── presentation/         # 表现层
│   │   │               │   ├── controller/       # REST API控制器
│   │   │               │   │   └── OrderController.java
│   │   │               │   └── dto/              # 数据传输对象
│   │   │               │       ├── OrderRequest.java
│   │   │               │       └── OrderResponse.java
│   │   │               ├── application/          # 应用层
│   │   │               │   ├── service/          # 应用服务
│   │   │               │   │   └── OrderAppService.java
│   │   │               │   └── event/            # 领域事件处理
│   │   │               │       └── OrderEventPublisher.java
│   │   │               ├── domain/               # 领域层
│   │   │               │   ├── entity/           # 实体
│   │   │               │   │   ├── Order.java   # 聚合根
│   │   │               │   │   └── OrderItem.java
│   │   │               │   ├── valueobject/      # 值对象
│   │   │               │   │   └── Address.java
│   │   │               │   ├── repository/       # 仓储接口
│   │   │               │   │   └── OrderRepository.java
│   │   │               │   ├── service/          # 领域服务
│   │   │               │   │   └── OrderDomainService.java
│   │   │               │   └── event/            # 领域事件
│   │   │               │       └── OrderCreatedEvent.java
│   │   │               ├── infrastructure/       # 基础设施层
│   │   │               │   ├── repository/       # 仓储实现
│   │   │               │   │   └── OrderRepositoryImpl.java
│   │   │               │   ├── mq/               # 消息队列集成
│   │   │               │   │   └── RocketMQProducer.java
│   │   │               │   └── config/           # 配置类
│   │   │               │       └── NacosConfig.java
│   │   ├── resources/
│   │   │   ├── application.yml                   # Spring Boot配置文件
│   │   │   └── nacos-config.properties           # Nacos配置
│   └── test/
│       └── java/
│           └── com/
│               └── ecommerce/
│                   └── order/
│                       └── OrderServiceTest.java
├── pom.xml                                       # Maven依赖文件
└── README.md                                     # 项目说明
文件结构说明
  1. 表现层(presentation)

    • OrderController:对外暴露REST API,比如创建订单、查询订单。
    • OrderRequest/OrderResponse:DTO用于接收和返回数据,避免直接暴露领域模型。
  2. 应用层(application)

    • OrderAppService:协调业务用例,比如调用领域服务创建订单、发布事件。
    • OrderEventPublisher:将领域事件发布到消息队列(如RocketMQ)。
  3. 领域层(domain)

    • Order:聚合根,包含订单的核心逻辑,比如添加订单项、计算总价。
    • OrderItem:实体,表示订单中的商品项。
    • Address:值对象,表示订单的配送地址。
    • OrderRepository:仓储接口,定义订单的持久化操作。
    • OrderDomainService:处理复杂的领域逻辑,比如订单状态转换。
    • OrderCreatedEvent:领域事件,表示订单已创建。
  4. 基础设施层(infrastructure)

    • OrderRepositoryImpl:仓储的具体实现,使用Spring Data JPA或MyBatis。
    • RocketMQProducer:集成RocketMQ发送消息。
    • NacosConfig:配置Nacos服务发现和配置管理。

四、贫血模型与充血模型

这两个模型是领域驱动设计中常见的设计模式:

贫血模型

在贫血模型中,领域对象只有属性和简单的 get/set 方法,所有的业务逻辑都放在服务(Service)中。虽然实现简单,但容易导致:

  • 领域模型与业务逻辑脱节。

  • 对象的行为和状态分散,不利于维护。

示例:POJO(Plain Old Java Object)形式的订单实体。

充血模型

充血模型是面向对象的体现。领域对象除了保存状态外,还负责与自身状态相关的行为。

示例:充血模型的订单实体。

充血模型的优势在于逻辑内聚,但需要适度设计,避免过于复杂。

参考文章:

  1. DDD是什么?用一个电商的例子来入门
  2. DDD新手入门:领域模型设计的七个核心概念
http://www.xdnf.cn/news/202771.html

相关文章:

  • 今日行情明日机会——20250428
  • NdrpGetAllocateAllNodesContext函数分析之三个内存区域的联系
  • 每日一题(12)TSP问题的贪心法求解
  • params query传参差异解析及openinstall跨平台应用
  • EMC isilon/PowerScale 如何收集日志
  • 【SAP ABAP 获取采购申请首次审批时间】
  • 【LLM开发】Unigram算法
  • 可编程控制器应用
  • 瞄定「舱驾融合」,黑芝麻智能的智驾平权「芯」路径
  • 大数据应用开发与实战(1)
  • Git技巧:Git Hook,自动触发,含实战分享
  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第四模块·Java特性专精 —— 第十六章 多线程:从pthread到JMM的升维
  • Atcoder Help 有关Atcoder 的介绍-1 涨分规则
  • 嵌入式开发学习日志Day11
  • GESP2024年9月认证C++八级( 第二部分判断题(6-10))
  • 在Linux系统中安装Anaconda的完整指南
  • (001)Excel 快捷键
  • 【RabbitMQ消息队列】(二)交换机模式详解
  • MTKAndroid12-13-开机应用自启功能实现
  • 【差分隐私】目标扰动机制(Objective Perturbation)
  • Android平台Unity引擎的Mono JIT机制分析
  • 前端如何使用Mock模拟数据实现前后端并行开发,提升项目整体效率
  • 计算机视觉进化论:YOLOv12、YOLOv11与Darknet系YOLOv7的微调实战对比
  • 单片机-89C51部分:7、中断
  • ZYNQ-自定义呼吸灯IP核以及PS-PL数据发送接收
  • 【Java学习笔记】传参机制
  • Vue 2 中 Vue 实例对象(vm)的所有核心方法,包含完整示例、使用说明及对比表格
  • 【Java】 使用 HTTP 响应状态码定义web系统返回码
  • 继承(c++版 非常详细版)
  • linux 环境下 c++ 程序打印 core dump 信息