DDD(领域驱动设计) 核心概念详解

在上一篇文章当中,我们简单讲解了DDD架构的部分概念,现在我们讲解一下大部分的核心概念

注意 每个公司的DDD架构的实现可能不大一样,也就是在架构方面 ,但是总体思想仍然是一致的

实体(Entity)

概念

实体是在相同限界上下文中具有唯一标识的领域模型,可变,通过标识判断同一性。例如用户、订单等,关键在于它们的身份(ID)而非属性值。

简单而言,就是实体类,但是需要注意一点,实体类中应具备当前类的服务, 也就是充血模型中服务聚合

举例

复制代码
// Java示例:Order实体
public class Order {
    private final String orderId; // 唯一标识
    private String customerId;
    private OrderStatus status;
    // 构造函数、Getter省略
    public Order(String orderId, String customerId) {
        this.orderId = orderId;
        this.customerId = customerId;
        this.status = OrderStatus.NEW;
    }
    // 领域行为:支付订单
    public void pay() {
        if (status != OrderStatus.NEW) {
            throw new IllegalStateException("订单不能支付");
        }
        this.status = OrderStatus.PAID;
    }
    // ... 其他业务逻辑方法
}

值对象(Value Object)

概念

一种没有唯一标识、通过属性值判断相等性的领域模型 ,他跟实体的区别就是,实体一般是有周期性的,会在业务流程中被追踪,值对象更多的是一种标识

举例

复制代码
// Java示例:Money值对象
public class Money {
    private final BigDecimal amount;
    private final String currency; // 币种

    public Money(BigDecimal amount, String currency) {
        if (amount.signum() < 0) throw new IllegalArgumentException("金额必须非负");
        this.amount = amount;
        this.currency = currency;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Money)) return false;
        Money other = (Money) o;
        return amount.equals(other.amount) && currency.equals(other.currency);
    }
    @Override
    public int hashCode() {
        return Objects.hash(amount, currency);
    }
    // 领域行为:累加金额
    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new IllegalArgumentException("币种不一致");
        }
        return new Money(this.amount.add(other.amount), this.currency);
    }
}

聚合根(Aggregate Root)

概念

聚合是一组相关实体和值对象的集合,在业务上表达统一意义,并在其内部保证一致性。聚合中有一个聚合根(Aggregate Root),它是聚合的唯一对外入口。

聚合根是聚合中最核心的实体,其他实体和值对象都从属于它。每个聚合必须有且只有一个聚合根(聚合也可只包含单一根实体)。聚合根在持久化和查找时发挥作用。

简单而言,就是将实体和值对象疯转在一起(注意,是有关联的实体和值对象)

举例

复制代码
// Java示例:Order聚合根与子对象
public class Order {
    private final String orderId;
    private final List<OrderItem> items = new ArrayList<>(); // 聚合内实体
    private OrderStatus status;

    public Order(String orderId) {
        this.orderId = orderId;
        this.status = OrderStatus.NEW;
    }
    public void addItem(String productId, int qty) {
        if (status != OrderStatus.NEW) {
            throw new IllegalStateException("已提交订单不可添加商品");
        }
        items.add(new OrderItem(productId, qty));
    }
    // 计算订单总价
    public Money totalPrice() {
        Money total = new Money(BigDecimal.ZERO, "CNY");
        for (OrderItem item : items) {
            total = total.add(item.getPrice());
        }
        return total;
    }
}
public class OrderItem {
    private final String productId;
    private final int quantity;
    private final Money price; // 值对象

    public OrderItem(String productId, int quantity) {
        this.productId = productId;
        this.quantity = quantity;
        this.price = fetchPriceFromCatalog(productId).multiply(quantity);
    }
    public Money getPrice() { return price; }
}

仓储(Repository)

概念

储是以持久化聚合根为职责的类或接口。它为领域层提供查找和持久化功能,屏蔽底层存储(数据库/ORM)实现差异。

一般来说,仓储是暴露给外界的接口,用来访问聚合根的数据

举例

复制代码
// Java示例:Order仓储接口
public interface OrderRepository {
    Order findById(String orderId);
    void save(Order order);
}

领域服务(Domain Service)

概念

领域服务是领域层的无状态服务,用于封装不属于单一实体或值对象的业务逻辑。通常是跨实体或跨聚合的操作,如复杂计算、领域算法等

一般来说就是mvc中的service,需要多个实体之间的相互调用的时候就会使用到

举例

复制代码
// Java示例:跨账户转账领域服务
public class TransferService {
    public void transfer(Account from, Account to, Money amount) {
        from.withdraw(amount);
        to.deposit(amount);
    }
}

应用服务(Application Service)

概念

应用服务位于应用层,用于组织和协调领域对象以完成特定业务用例。它为上层(如UI)提供接口,负责调用领域模型、控制事务并返回结果。

举例

复制代码
// Java示例:订单应用服务
public class OrderApplicationService {
    private final OrderRepository orderRepo;
    public OrderApplicationService(OrderRepository repo) {
        this.orderRepo = repo;
    }
    public String createOrder(String customerId, List<OrderItem> items) {
        // 创建聚合根并执行业务操作
        Order order = new Order(UUID.randomUUID().toString());
        for (OrderItem item : items) {
            order.addItem(item.getProductId(), item.getQuantity());
        }
        orderRepo.save(order);
        return order.getOrderId();
    }
}

应用服务和领域服务的关系

领域服务一般指的是实体类之间的相互调用,属于业务中的逻辑调用,而应用服务是对领域服务的调用

领域事件(Domain Event)

概念

领域事件是在业务领域中已经发生的关键事实或状态变化。它反映领域模型中某个实体或聚合根的重要变化,并可通知系统其他部分。于解耦和记录业务流程中的重要事件。例如订单"已支付"(OrderPaid)、库存"低于安全线"等。领域事件可以触发其他处理(如发送通知、更新查询模型等)。

工厂(Factory)

概念

复制代码
工厂是负责构建领域模型(实体或值对象)的类或方法
。它封装对象创建的复杂逻辑,如参数验证、赋予默认值等。

举例

复制代码
// C#示例:Order工厂
public static class OrderFactory {
    public static Order CreateOrder(string customerId, IEnumerable<OrderItem> items) {
        var order = new Order(Guid.NewGuid().ToString());
        foreach (var item in items) {
            order.AddItem(item.ProductId, item.Quantity);
        }
        return order;
    }
}

界限上下文

概念

限界上下文是DDD的核心战略模式,定义了模型的边界。每个上下文使用一致的术语和规则,不同上下文可以有相同名词但含义不同(模型在上下文内保持一致性)。在大型系统中,不同子域有不同模型时,需要划分限界上下文。例如电商系统中,订单、库存、支付分别属于不同限界上下文,各自处理相应领域。 也就是每个业务可以任务是一个上下文,一个上下文中的语法应该是一致的,对外暴露api接口即可

上下文映射(Context Mapping)

概念

定义: 上下文映射是描述限界上下文之间关系的模式集合,通常用图示表示。常见模式包括合作(Partnership)、共享内核(Shared Kernel)、客户-供应方(Customer-Supplier)、遵奉者(Conformist)、反腐层(ACL)、开放主机服务(OHS)等。

反腐层(Anti-Corruption Layer)

概念

在不同限界上下文或系统之间构建的适配层,用于翻译和隔离模型。它将一个系统的请求转换为本系统的模型,防止外部模型污染本领域模型。有点类似于适配器,来作为防腐服务。 就是一个业务需要另外的业务时,应只暴露本身上下文的模型,而不是使用对面的领域对象。

事件风暴(Event Storming)

概念

事件风暴是一种以工作坊形式进行的协作领域建模方法,由 Alberto Brandolini 提出。参与者(开发者和领域专家)通过贴便利贴标记领域事件、命令、聚合等元素,快速探索和分析复杂业务流程。

相关推荐
ego.iblacat1 小时前
MySQL 数据库操作
数据库·mysql·adb
赵渝强老师1 小时前
【赵渝强老师】高斯数据库(openGauss)的逻辑存储结构
数据库·postgresql·opengauss·gaussdb·国产数据库·高斯数据库
oem1102 小时前
C++中的访问者模式变体
开发语言·c++·算法
Fu-dada2 小时前
Spring Boot 开发接口指南
spring boot
Aawy1202 小时前
Python生成器(Generator)与Yield关键字:惰性求值之美
jvm·数据库·python
梦想的旅途22 小时前
API 驱动:实现企业微信外部群自动化管理与效率升级
数据库·windows
SuperEugene2 小时前
JS/TS 编码规范实战:Vue 场景变量 / 函数 / 类型标注避坑|编码语法规范篇
开发语言·javascript·vue.js
暮冬-  Gentle°2 小时前
C++中的工厂方法模式
开发语言·c++·算法
大傻^2 小时前
LangChain4j Spring Boot Starter:自动配置与声明式 Bean 管理
java·人工智能·spring boot·spring·langchain4j