关于聚合根,领域事件的那点事---深入浅出理解DDD

科技资讯 投稿 6200 0 评论

关于聚合根,领域事件的那点事---深入浅出理解DDD

作者:京东物流 赵勇萍

前言

在此,通过小demo的方式跟大家分享一下我对DDD中战术层级的理解,算是抛砖引玉,该理解仅代表我个人在现阶段的一个理解,也可能未来随着业务经验深入,还会有不同的理解。

一个简单的demo业务场景

话不多说,我先抛出我自己假设的一个业务场景,就是我们熟知的电商网站下单购物的场景。具体细节如下:

1. 实体:

• 订单:拥有唯一标识、下单时间、状态等属性。订单包含多个订单项。

2. 值对象:

3. 领域事件:

• 订单创建事件:当用户下单时触发该事件,包含订单信息、商品信息等数据。

• 订单发货事件:当商家发货时触发该事件,包含订单信息、快递公司、快递单号等数据。

4. 聚合根:

• 订单聚合根:包含订单实体和相关的值对象,负责订单的创建、修改、查询等操作。

5. 对外接口服务:

• 支付订单接口:用户完成支付后,系统更新订单状态,并触发订单支付事件。

• 查询订单接口:用户可以根据订单号等条件查询自己的订单信息。

demo的java代码实现

好了,有了以上我们对业务场景的充分剖析,确定了子域,接下来我们该写我们的代码。

    商品实体类:
// 省略getter/setter方法
public class Product {
    private Long id;
    private String name;
    private BigDecimal price;
    private Integer stock;
}

2. 订单实体类

// 省略getter/setter方法
public class Order {
    private Long id;
    private LocalDateTime createTime;
    private Integer status;
    private List orderItems;
}

3. 订单项实体类

// 省略getter/setter方法
public class OrderItem {
    private Long id;
    private Product product;
    private Integer quantity;
    private BigDecimal price;
}

4. 地址值对象

// 省略getter/setter方法 
public class Address {
    private String province;
    private String city;
    private String district;
    private String detail;
}

5. 领域事件类

//订单创建领域事件
public class OrderCreatedEvent {
    private Order order;
    private List orderItems;

    public OrderCreatedEvent(Order order, List orderItems {
        this.order = order;
        this.orderItems = orderItems;
    }
}


//订单支付领域事件
public class OrderPaidEvent {
    private Order order;
    private BigDecimal amount;

    public OrderPaidEvent(Order order, BigDecimal amount {
        this.order = order;
        this.amount = amount;
    }
}

//订单
public class OrderShippedEvent {
    private Order order;
    private String expressCompany;
    private String expressNo;

    public OrderShippedEvent(Order order, String expressCompany, String expressNo {
        this.order = order;
        this.expressCompany = expressCompany;
        this.expressNo = expressNo;
    }
}

6. 商品聚合根

public class ProductAggregate {
    private ProductService productService;

    public void createProduct(Product product {
        productService.create(product;
    }

    public void updateProduct(Product product {
        productService.update(product;
    }

    public void deleteProduct(Long productId {
        productService.delete(productId;
    }

    public Product getProductById(Long productId {
        return productService.getById(productId;
    }
}

7. 订单聚合根

public class OrderAggregate {
    private OrderService orderService;

    public void createOrder(Order order, List orderItems {
        orderService.create(order;
        // 触发订单创建事件 
        DomainEventPublisher.publish(new OrderCreatedEvent(order, orderItems;
    }

    public void payOrder(Long orderId, BigDecimal amount {
        orderService.pay(orderId, amount;
        // 触发订单支付事件
        DomainEventPublisher.publish(new OrderPaidEvent(orderService.getById(orderId, amount;
    }

    public void shipOrder(Long orderId, String expressCompany, String expressNo {
        orderService.ship(orderId, expressCompany, expressNo;
        // 触发订单发货事件 
        DomainEventPublisher.publish(new OrderShippedEvent(orderService.getById(orderId, expressCompany, expressNo;
    }

    public Order getOrderById(Long orderId {
        return orderService.getById(orderId;
    }
}

总结

通过以上demo,对于实体和值对象,大家会很好理解,并且很直观。但是,我额外想重点解释一下聚合根和领域事件的概念

从上面的demo可以看出,在合根类中,我们定义了商品和订单的增、删、查等操作,并且为订单定义了创建订单、支付订单、发货等业务逻辑代码。

所以说,真正的聚合根内的方法是基于充血模型封装的,而不是仅仅是对对象的数据封装。在聚合根中,对象不仅封装了数据,还包含了相应的行为和业务逻辑。这意味着在一个聚合根中,对象可以自己处理自己的业务逻辑,而不需要外部的控制。就如同demo中所写的那样,订单对象可能包含一些关于订单处理和交付的方法,如确认订单、取消订单、发货等。

领域事件是DDD中最重要的概念之一,他是解决子域之间耦合的重要手段,因为它们提供了一种将领域概念和业务语言转化为代码的方法。当一个领域事件发生时,它会触发一些操作,这些操作可能会更改系统的状态,也可能会导致其他领域事件的发生。通过对领域事件进行建模,我们可以更好地了解业务过程并设计出更加符合实际需求的系统。

    事件名称:这个名称应该能够简洁明了地描述事件所代表的业务意义。

  1. 发送者和接收者:发送者通常是触发事件的对象,接收者则是事件处理的对象。

总之,领域事件是DDD架构中非常重要的概念,它可以帮助我们更好地理解业务过程,设计出更加符合实际需求的系统,并提高系统的可维护性和可扩展性。

编程笔记 » 关于聚合根,领域事件的那点事---深入浅出理解DDD

赞同 (25) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽