《小型支付商城系统》项目(一)DDD架构入门
目录
1.DDD架构
1.1充血模型
1.2领域模型
1.2.1实体
1.2.2值对象
1.2.3聚合
1.2.4领域服务
1.2.5工厂
1.2.6仓储(Repository)
2.DDD建模
3.DDD工程模型
项目介绍:知识星球 | 深度连接铁杆粉丝,运营高品质社群,知识变现的工具
开篇介绍视频:开篇介绍(学习指引、环境说明、工程讲解)-知识星球
开篇介绍文档:《小型支付商城系统》开篇介绍(学习指引、环境说明、工程讲解)
MVC与DDD架构的区别:浅谈架构设计:MVC架构与DDD架构【开发实践】_ddd架构和mvc架构区别-CSDN博客
1.DDD架构
视频:第1-1节 DDD 架构概念-知识星球
文章:《小型支付商城系统》第1-1节 DDD 架构概念
domain-driven design,是一种软件设计方法
1.1充血模型
在领域驱动设计(Domain-Driven Design, DDD)中,充血模型(Rich Domain Model) 是一种面向对象设计的思想,强调将数据和行为封装到同一个领域对象中,使得领域对象不仅仅是数据的载体,更是业务逻辑的核心。
不要只是把充血模型,仅限于一个类的设计和一个类内的方法设计。充血还可以是整个包结构,一个包下包括了用于实现此包 Service 服务所需的各类零部件(模型、仓储、工厂),也可以被看做充血模型。
示例:
public class Order {
private Long id;
private String status;
private Double amount;
public Order(Long id, Double amount) {
this.id = id;
this.amount = amount;
this.status = "NEW";
}
public void pay() {
if (!"NEW".equals(this.status)) {
throw new IllegalStateException("Only NEW orders can be paid.");
}
this.status = "PAID";
}
public void cancel() {
if ("PAID".equals(this.status)) {
throw new IllegalStateException("Paid orders cannot be canceled.");
}
this.status = "CANCELED";
}
public String getStatus() {
return status;
}
}
充血模型的适用场景:
- 复杂业务场景:业务逻辑较多且变化频繁
- 高内聚低耦合:希望将数据和业务逻辑绑定在一起
- 需要长时间维护和扩展的系统:避免贫血模型导致的业务逻辑分散
1.2领域模型
领域模型指特定业务领域内,业务规则、策略以及业务流程的抽象和封装。它由实体(Entity)、值对象(Value Object)、聚合(Aggregate)、领域服务(Domain Service)等元素组成。简单理解就是领域模型是业务的蓝图,用面向对象的方式描述业务领域的核心概念及其关系。
领域模型的核心组成:
1.2.1实体
- 含义:具有唯一标识符(ID),即使其他属性值相同,也可以区分不同实体
- 特点:身份唯一,生命周期独立
- 示例:在电商系统中,
订单(Order)
就是一个实体,每个订单都有唯一的订单编号(ID)
public class Order {
private String orderId; // 唯一标识符
private String customerId;
private double amount;
// Getters, Setters, Business Methods...
}
1.2.2值对象
- 含义:不具有唯一标识符,其数据属性决定其身份
- 特点:不可变、可复用、无唯一标识
- 示例:在订单系统中,
地址(Address)
就是一个值对象
public class Address {
private String city;
private String street;
private String zipCode;
// Constructor, Getters...
}
1.2.3聚合
- 含义:由实体和值对象组成的聚合根,表示业务领域中的一个整体
- 聚合根:聚合的入口点,控制聚合内部实体和值对象的访问
- 特点:保证数据一致性、事务性
- 示例:订单聚合包含订单实体、订单项、配送地址等
public class Order {
private String orderId; // 聚合根
private List<OrderItem> items;
private Address shippingAddress;
}
1.2.4领域服务
- 含义:一些逻辑无法归属到任何一个实体或值对象上时,将其抽取为一个领域服务
- 特点:无状态,专注于跨实体或聚合的操作
- 示例:支付服务、库存服务
public class PaymentService {
public void processPayment(Order order, Payment payment) {
// 支付处理逻辑
}
}
1.2.5工厂
- 含义:用于创建复杂对象或聚合根,避免直接在业务代码中进行复杂的对象构建
- 特点:封装对象创建逻辑,保证聚合的完整性
- 示例:订单工厂
public class OrderFactory {
public Order createOrder(String customerId, List<OrderItem> items) {
// 创建订单逻辑
return new Order(customerId, items);
}
}
1.2.6仓储(Repository)
- 含义:用于持久化和检索领域对象,通常是对数据库访问的封装
- 特点:提供领域对象的存储和查询接口
- 示例:订单仓储
public interface OrderRepository {
void save(Order order);
Order findById(String orderId);
}
Repository模式是DDD中的一个核心概念,它有助于保持领域模型的聚焦和清晰,同时提供了灵活、可测试和可维护的数据访问策略。
2.DDD建模
视频:第1-2节 DDD 建模方法-知识星球
文档:《小型支付商城系统》第1-2节 DDD 建模方法
四色建模(风暴事件)是整个 DDD 架构中用于工程拆分界限上下文的非常重要的实践手段。通过建模过程快速识别业务领域中的关键事件和核心流程,为后面详细设计和代码开发做指导。
可以把整个过程理解为,为工程开发提供面向对象设计,涵盖:领域拆分、界限串联、功能聚合。所以相比Service + 数据模型
的贫血开发方式,DDD 前期需要付出更多的设计成本,但对于软件的长周期迭代,这样的好处是非常大的。
如何建模?
DDD 的建模过程,是以一个用户为起点,通过行为命令,发起行为动作,串联整个业务。(面向对象)而这个用户的起点最初来自于用例图的分析。
3.DDD工程模型
视频:第1-3节 DDD 工程模型-知识星球
文档:《小型支付商城系统》第1-3节 DDD 工程模型
工程结构的存在作用目的简而言之就是:在工程实现时,在哪个层访问数据库、哪个层使用缓存、哪个层调用外部接口、哪个层做功能实现...
架构的目的:让不同的职责分配到不同的区域内
如果用用 MVC 的分层结构承接这些内容就如下图所示:
越来越多的内容被填充到工程中,这个时候你细心的查看架构,就会发现原本的 MVC 结构其实已经变的非常混乱了。一个 Service 中为了实现自己的功能,要引入一堆的东西,这些原子的功能与 Service 自身的服务耦合在一块。也导致了工程的维护成本越来越大。
后来提出了诸如六边形架构、洋葱架构和菱形架构,他们的目标都是以领域服务为核心,隔离内部实现和外部资源的耦合。