前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >泣血之作——初级领域设计详解,附带案例与代码

泣血之作——初级领域设计详解,附带案例与代码

原创
作者头像
裕贞
发布2025-02-17 13:45:32
发布2025-02-17 13:45:32
560
举报

一、核心理论概念

1.1 领域设计三大支柱

代码语言:mermaid
复制
graph TD 
    A[战略设计] --> B(限界上下文)
    A --> C(上下文映射)
    D[战术设计] --> E(实体)
    D --> F(值对象)
    D --> G(聚合根)
    H[实现模式] --> I(仓储模式)
    H --> J(领域服务)

1.2 核心要素说明

概念

特征

示例

实体

唯一标识,可变状态

订单(Order)

值对象

不可变,无标识

金额(Money)

聚合根

业务一致性边界

订单聚合根

领域服务

处理跨聚合的业务逻辑

订单服务

二、电商订单系统案例

2.1 业务场景描述

需求:实现电商订单创建与库存扣减的原子操作

业务规则:

  1. 订单金额必须大于0
  2. 库存不足时禁止下单
  3. 订单状态需按流程流转(创建→已支付→已完成)

2.2 领域模型设计

代码语言:java
复制
// 值对象示例 
public record Money(BigDecimal amount, Currency currency) {
    public Money {
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("金额必须大于0");
        }
    }
}
 
// 实体示例 
public class OrderItem {
    private final String productId;
    private final int quantity;
    private final Money price;
    
    // 构造函数与业务方法省略...
}
 
// 聚合根示例 
public class Order {
    private String orderId;
    private List<OrderItem> items;
    private OrderStatus status;
    
    public void confirmPayment() {
        if (status != OrderStatus.CREATED) {
            throw new IllegalStateException("订单状态异常");
        }
        status = OrderStatus.PAID;
    }
}

三、完整Java实现

3.1 项目结构

代码语言:txt
复制
src/main/java/com/example/ddd/
├── model 
│   ├── Order.java          # 聚合根 
│   ├── OrderItem.java      # 实体 
│   └── Money.java          # 值对象 
├── service 
│   └── OrderService.java   # 领域服务 
└── repository 
    └── InventoryRepo.java  # 仓储接口 

3.2 代码类图

代码语言:mermaid
复制
classDiagram 
    class Money {
        <<Value Object>>
        -BigDecimal amount 
        -Currency currency 
        +Money(BigDecimal, Currency)
        +add(Money) Money 
        +multiply(int) Money 
    }
 
    class OrderItem {
        <<Entity>>
        -String productId 
        -int quantity 
        -Money price 
        +OrderItem(String, int, Money)
        +productId() String 
        +quantity() int 
        +price() Money 
    }
 
    class Order {
        <<Aggregate Root>>
        -String orderId 
        -List<OrderItem> items 
        -OrderStatus status 
        -LocalDateTime createTime 
        +Order(String, List~OrderItem~)
        +confirmPayment() void 
        +calculateTotal() BigDecimal 
        +getDomainEvents() List~DomainEvent~
    }
 
    class OrderService {
        <<Domain Service>>
        -InventoryRepository inventoryRepo 
        +placeOrder(List~OrderItem~) Order 
    }
 
    class InventoryRepository {
        <<Repository Interface>>
        +getStock(String) int 
        +reduceStock(String, int) void 
        +addStock(String, int) void 
    }
 
    class OrderStatus {
        <<Enumeration>>
        CREATED 
        PAID 
        COMPLETED 
        CANCELLED 
    }
 
    Order "1" *-- "*" OrderItem : contains 
    OrderItem "1" -- "1" Money : uses 
    OrderService ..> InventoryRepository : depends 
    OrderService ..> Order : creates 
    OrderStatus <.. Order : uses 

3.3 核心代码实现

值对象(Money)

代码语言:java
复制
public record Money(BigDecimal amount, Currency currency) implements Serializable {
    
    public Money add(Money other) {
        if (!currency.equals(other.currency)) {
            throw new CurrencyMismatchException();
        }
        return new Money(amount.add(other.amount), currency);
    }
    
    public Money multiply(int quantity) {
        return new Money(amount.multiply(BigDecimal.valueOf(quantity)), currency);
    }
}

聚合根(Order)

代码语言:java
复制
public class Order {
    private String orderId;
    private List<OrderItem> items;
    private OrderStatus status;
    private LocalDateTime createTime;
 
    public Order(String orderId, List<OrderItem> items) {
        this.orderId = Objects.requireNonNull(orderId);
        this.items = new ArrayList<>(Objects.requireNonNull(items));
        this.status = OrderStatus.CREATED;
        this.createTime = LocalDateTime.now();
    }
 
    public void confirmPayment() {
        if (status != OrderStatus.CREATED) {
            throw new IllegalOrderStateException();
        }
        status = OrderStatus.PAID;
    }
 
    public BigDecimal calculateTotal() {
        return items.stream()
                .map(item -> item.price().multiply(item.quantity()))
                .reduce(Money::add)
                .orElseThrow()
                .amount();
    }
}

领域服务(OrderService)

代码语言:java
复制
public class OrderService {
    private final InventoryRepository inventoryRepo;
 
    public Order placeOrder(List<OrderItem> items) {
        // 库存检查 
        items.forEach(item -> {
            int available = inventoryRepo.getStock(item.productId());
            if (available < item.quantity()) {
                throw new InsufficientStockException();
            }
        });
 
        // 创建订单 
        Order newOrder = new Order(UUID.randomUUID().toString(), items);
        
        // 扣减库存 
        items.forEach(item -> 
            inventoryRepo.reduceStock(item.productId(), item.quantity()));
        
        return newOrder;
    }
}

四、案例分析与成果

4.1 设计分析

  1. 聚合边界控制:
    • Order作为聚合根,封装订单状态变更
    • 库存变更通过领域服务协调
  2. 业务规则内化:
代码语言:java
复制
// 在Money值对象中内嵌验证规则 
public Money(BigDecimal amount, Currency currency) {
    if (amount.compareTo(BigDecimal.ZERO) <= 0) {
        throw new IllegalArgumentException("金额必须大于0");
    }
    this.amount = amount.setScale(2, RoundingMode.HALF_UP);
    this.currency = currency;
}
  1. 领域服务协调:
代码语言:txt
复制
sequenceDiagram 
    participant Client 
    participant OrderService 
    participant InventoryRepo 
    participant Order 
    
    Client->>OrderService: placeOrder(items)
    OrderService->>InventoryRepo: getStock(productId)
    InventoryRepo-->>OrderService: stock 
    OrderService->>Order: new()
    OrderService->>InventoryRepo: reduceStock()
    OrderService-->>Client: return Order 

4.2 运行示例

代码语言:java
复制
public class Application {
    public static void main(String[] args) {
        // 初始化仓储 
        InventoryRepository repo = new MemoryInventoryRepo();
        repo.addStock("P1001", 10);
        
        // 创建订单项 
        List<OrderItem> items = List.of(
            new OrderItem("P1001", 2, new Money(new BigDecimal("99.99"), Currency.USD))
        );
        
        // 执行下单 
        OrderService service = new OrderService(repo);
        Order order = service.placeOrder(items);
        
        System.out.println("订单创建成功:" + order);
        System.out.println("当前库存:" + repo.getStock("P1001"));
    }
}
 
// 输出结果:
// 订单创建成功:Order[total=199.98 USD]
// 当前库存:8 

五、设计总结

5.1 关键收益

  • 业务显性化:订单状态机直接反映业务规则
  • 可维护性:库存管理逻辑集中处理
  • 可测试性:领域对象可独立单元测试

5.2 改进方向

  1. 引入领域事件(如OrderPlacedEvent)
  2. 实现真正的持久化仓储
  3. 增加分布式事务处理
  4. 实施CQRS模式分离读写操作
代码语言:java
复制
// 改进示例:领域事件发布 
public class Order {
    // ...
    private List<DomainEvent> domainEvents = new ArrayList<>();
    
    public void confirmPayment() {
        // ...原有逻辑...
        domainEvents.add(new OrderPaidEvent(this.orderId));
    }
    
    public List<DomainEvent> getDomainEvents() {
        return Collections.unmodifiableList(domainEvents);
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档