DDD(领域驱动设计),是现在非常火热的架构设计,而且大厂面试也经常考察,下面我就全面来详解DDD原理@mikechen
DDD
DDD,全称是“Domain-Driven Design”,翻译过来就是领域驱动设计,是一种以领域为中心的软件开发方法论。
DDD,强调通过深入理解业务领域,并将领域知识明确地融入到系统设计中,从而来构建复杂的软件系统。
DDD适用于各种复杂的业务系统,尤其适用于:业务逻辑复杂、系统规模庞大…等应用场景。
DDD原理
DDD强调建立清晰的领域模型,使开发人员、和业务人员,能够以共同的语言进行交流。
DDD,将系统架构分为多个层次,如下图所示:
主要会包含,如下四层:
领域层(Domain Layer)
包含业务逻辑、和领域模型,聚合了实体、和值对象…等等;
应用层(Application Layer)
负责:协调应用程序的行为,处理用户请求;
协调领域层,调用领域服务来完成用户请求。
接口层(Interface Layer)
提供用户、与系统交互的接口,比如:通过HTTP…等协议,接收用户请求。
以及,将领域模型转换为DTO(Data Transfer Object),以便于传输。
基础设施层(Infrastructure Layer)
处理数据持久化、和外部服务交…等等。
这里面,最重要的就是领域层。
领域模型
领域模型,将业务领域抽象成一个模型,这个模型包含了领域中的实体、值对象、聚合、服务…等。
实体
具有唯一标识符的对象,代表业务中的一个重要概念,比如:用户、订单、产品…等。
public class User { private String userId; // 唯一标识 private String name; private String email; public User(String userId, String name, String email) { this.userId = userId; this.name = name; this.email = email; } public String getUserId() { return userId; } public String getName() { return name; } public String getEmail() { return email; } public void updateEmail(String newEmail) { this.email = newEmail; } }
值对象
没有唯一标识符的对象,通常用来描述实体的特征,比如:地址、或日期…等等。
public class Address { private String street; private String city; private String country; // ... 其他属性 // 构造方法,确保不可变性 public Address(String street, String city, String country) { this.street = street; this.city = city; this.country = country; } // 只提供getter方法,不提供setter方法 }
聚合
由相关实体、和值对象,组成的集合,是数据修改、和持久化的基本单元。
public class Order { private Long id; private User customer; private List<OrderItem> items; private Address shippingAddress; // ... 其他属性和方法 // 构造方法,设置聚合根 public Order(User customer, Address shippingAddress) { this.customer = customer; this.shippingAddress = shippingAddress; this.items = new ArrayList<>(); } public void addItem(OrderItem item) { items.add(item); } }
- 聚合根:
Order
是聚合根,负责维护聚合内部的一致性。 - 实体:
User
、OrderItem
都是实体。 - 值对象:
Address
是值对象
限界上下文
在领域驱动设计(DDD)中,限界上下文(Bounded Context) 是一个非常重要的概念。
它定义了一个明确的领域边界,在这个边界内,领域模型有着一致的业务语义和规则。
简单来说,限界上下文就是将一个复杂的领域划分成多个小的、可管理的子域,每个子域都有自己独立的模型。
领域服务
封装一些领域相关的操作,不属于任何实体、或值对象。
当一个操作涉及多个聚合时,可以使用领域服务来协调它们。
比如:我们有一个电商系统,其中涉及到订单、产品和库存…等概念。
当用户下单时,我们需要检查库存是否充足,如果充足则创建订单,否则拒绝订单。
这个过程涉及到多个聚合(订单、产品)之间的交互,关注领域模型内部的业务逻辑,是领域层的核心实现。
mikechen睿哥
mikechen睿哥,十余年BAT架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》