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

学习笔记八

领域驱动设计核心概念
为什么需要DDD?
java
// 传统CRUD开发的痛点
@Service
public class OrderService {

// 贫血模型:只有数据,没有业务逻辑
@Data
public class Order {private Long id;private Long userId;private BigDecimal amount;private String status;private List<OrderItem> items;// 只有getter/setter,没有业务方法
}// 业务逻辑散落在Service中
public void submitOrder(Order order) {// 1. 校验库存checkInventory(order);// 2. 计算金额calculateAmount(order);// 3. 检查用户余额checkUserBalance(order);// 4. 扣减库存reduceInventory(order);// 5. 创建订单saveOrder(order);// 6. 发送消息sendOrderCreatedEvent(order);
}

}

/*
问题:

  1. 业务逻辑无法复用

  2. 领域知识丢失

  3. 需求变更困难

  4. 代码难以理解
    */
    DDD核心概念
    java
    // 1. 实体(Entity):有唯一标识,可变
    @Getter
    public class Order {
    private final OrderId id; // 值对象作为ID
    private OrderStatus status; // 状态枚举
    private Money totalAmount; // 值对象
    private List items;
    private DeliveryAddress deliveryAddress;

    // 实体有业务行为
    public void addItem(Product product, int quantity) {
    // 业务规则:不能添加已取消订单的商品
    if (this.status == OrderStatus.CANCELLED) {
    throw new OrderAlreadyCancelledException();
    }

     OrderItem item = new OrderItem(product, quantity);this.items.add(item);this.totalAmount = calculateTotalAmount(); // 重新计算总额
    

    }

    public void submit() {
    // 业务规则:订单必须有商品
    if (items.isEmpty()) {
    throw new EmptyOrderException();
    }

     // 业务规则:金额必须大于0if (totalAmount.lessThan(Money.ZERO)) {throw new InvalidOrderAmountException();}this.status = OrderStatus.SUBMITTED;registerEvent(new OrderSubmittedEvent(this.id));
    

    }

    public void cancel() {
    // 业务规则:已支付的订单不能取消
    if (this.status == OrderStatus.PAID) {
    throw new PaidOrderCannotBeCancelledException();
    }

     this.status = OrderStatus.CANCELLED;registerEvent(new OrderCancelledEvent(this.id));
    

    }
    }

// 2. 值对象(Value Object):无标识,不可变
@Value
public class Money {
BigDecimal amount;
Currency currency;

// 业务方法:加法(返回新对象,不修改原对象)
public Money add(Money other) {if (!this.currency.equals(other.currency)) {throw new CurrencyMismatchException();}return new Money(this.amount.add(other.amount), this.currency);
}// 业务规则验证
public boolean isGreaterThan(Money other) {return this.amount.compareTo(other.amount) > 0;
}

}

// 3. 聚合(Aggregate):一致性边界
public class Order extends AggregateRoot {

private List<OrderItem> items;      // 聚合内的实体
private Payment payment;              // 聚合内的值对象
private DeliveryInfo deliveryInfo;    // 聚合内的值对象// 聚合内的一致性规则
public void pay(CreditCard card) {// 规则1:只能支付已提交的订单if (this.status != OrderStatus.SUBMITTED) {throw new InvalidOrderStatusException();}// 规则2:支付金额必须等于订单总额Payment payment = new Payment(this.totalAmount, card);this.payment = payment;this.status = OrderStatus.PAID;registerEvent(new OrderPaidEvent(this.id));
}// 通过ID引用其他聚合
private UserId userId;  // 只引用ID,不直接引用User聚合

}

// 4. 领域服务(Domain Service):跨多个聚合的业务逻辑
@Service
@DomainService
public class OrderPlacementService {

private final OrderRepository orderRepository;
private final InventoryService inventoryService;
private final PaymentService paymentService;public Order placeOrder(Order order, PaymentInfo payment) {// 跨聚合的业务逻辑// 1. 检查库存inventoryService.checkAvailability(order.getItems());// 2. 创建订单(Order聚合的行为)order.submit();// 3. 处理支付(Payment聚合的行为)payment.process(order.getTotalAmount());// 4. 保存订单orderRepository.save(order);return order;
}

}

// 5. 领域事件(Domain Event):记录重要事件
@Getter
public class OrderSubmittedEvent extends DomainEvent {
private final OrderId orderId;
private final Money totalAmount;
private final LocalDateTime submittedAt;

public OrderSubmittedEvent(OrderId orderId, Money totalAmount) {this.orderId = orderId;this.totalAmount = totalAmount;this.submittedAt = LocalDateTime.now();
}

}

// 事件监听器
@Component
public class OrderEventListener {

@EventListener
public void handleOrderSubmitted(OrderSubmittedEvent event) {// 1. 发送通知sendNotification(event);// 2. 更新统计updateStatistics(event);// 3. 触发后续流程startWorkflow(event);
}

}

http://www.jsqmd.com/news/468707/

相关文章:

  • Kruskal 重构树
  • 【算法二十二】 739. 每日温度 42.接雨水
  • 基于Python的汽车保养系统设计与实现毕业设计
  • Meta发布四款Broadcom定制AI芯片,性能超越商用产品
  • flask:接收json参数
  • 量获取产品详情 小牛三下五除二就干上线了 代码那是写的干净又漂亮,没有一行多余的代码 只是性能有一点点瑕疵 每个商品获取要.秒,获取 ...
  • oceanbase-长事务排查
  • 市面上口碑好的百联OK卡回收平台推荐 - 京顺回收
  • 大模型推理服务架构优化指南(非常详细),vLLM扩缩容从入门到精通,收藏这一篇就够了!
  • OpenClaw安装与github账号注册
  • 2026年进销存软件十大权威排名,这5款让中小商家效率翻倍!
  • WAF绕过技巧与原理深度剖析
  • 中小企业也能拍电影级宣传片?山间清风‘轻量高质’套餐改写潍坊营销规则
  • 每天浪费 分钟杀端口?我开发了一个工具终结这种痛苦
  • 四川新脉动科技 × 搭贝零代码:制造业“专精特新“企业的数字化升级样本
  • 2026年一物一码防伪公司实力哪家强?顶讯科技稳居行业前列
  • 【一步步开发AI运动APP】十三、如何进行运动开始前的站位预检,提升用户体验
  • 2026年制造业人事系统推荐:10款支持复杂考薪的主流产品测评与对比
  • 探索MATLAB中考虑能源集线器的电热综合能源市场双层出清模型
  • Ant Design Vue Popover控件抖动
  • 国内可用OpenClaw安装教程
  • 频模式从底层上的了解,这一篇主要记录一下带通采样定理的知识,下一篇会涉及到三种混频模式的配置不同 在这里采样和频谱混叠等本科基础知识 ...
  • (持续更新 2026) 一文看懂各 AI 模型能力, 理清模型、应用与公司之间关系, 选择最适合业务的模型? #002
  • 文档也很齐全。但是在统信系统中部署和打包 Avalonia 程序为安装包,我是从来都没有这样做过的。其实,在 Windows 平台下 ...
  • 【wail框架】web+go的混合架构简要指南
  • 服务器监控集中式部署方案 V5.0(全量详细版)
  • 【Linux系统安装、配置mysql数据库详细过程,亲自部署成功后分享mysql安装过程,ARM架构安装、配置 mysql,包细节,各种系统架构和版本都适用!】
  • 计算机系统基础知识(补充):硬件篇之指令系统详解
  • 导师又让重写?千笔AI,一键生成论文神器
  • OpenClaw踩坑记录