领域驱动的设计实用程序类和实体中的通过存储库

时间:2014-04-07 21:39:18

标签: java domain-driven-design

问题涉及在实体中注入存储库和实用程序类。

背景

实体不直接使用存储库,而是将其传递给需要强制执行某些业务规则的策略。

有问题的实用程序类有助于验证模型和图像处理功能。验证实用程序将JSR 303验证应用于模型,该模型在创建时检查实体是否有效(自定义JSR 303注释也用于某些业务规则)。保存订单后会调用图像实用程序(保留后)并上传与订单相关的图像。这是在持久化后完成的,因为需要有关订单的ID。

问题

注入实体的所有这些依赖项感觉不对。困境是是否将所有(或某些,哪些?)移出域对象并将它们移动到其他地方? (如果是的话,那么什么是正确的地方?)或者这是否是分析瘫痪的情况?

例如,该策略可确保满足某些业务规则。是否应该将其取出,因为它需要存储库?我的意思是它需要在实体执行该更新时运行,所以我真的想要丢失该封装吗?

public class OrderFactory {

  // This could be autowired
  private IOrderRepository orderRepository;
  private ValidationUtils validationUtils;
  private ImageUtils imageUtils;

  public OrderFactory( IOrderRepository orderRepository, ValidationUtils validationUtils, ImageUtils imageUtils ) {
    this.orderRepository = orderRepository;
    this.validationUtils = validationUtils;
    this.imageUtils = imageUtils;
  }

  public Order createOrderFromSpecialOrder( SpecialOrderDTO dto ) {
    Order order = (dto.hasNoOrderId()) ? new Order() : orderRepository.findOrderById(dto.getOrderId());

    order.updateFromSpecialOrder( orderRepository, validationUtils, imageUtils, dto.getSpecialOrderAttributes(), dto.getImage());

    return order;
  }
}


public class Order {
  private IOrderRepository orderRepository;
  private ValidationUtils validationUtils;
  private ImageUtils imageUtils;
  private byte[] image;

  protected Order() {}

  protected void updateFromSpecialOrder( IOrderRepository orderRepository, ValidationUtils validationUtils, ImageUtils imageUtils, ISpecialOrderAttributes attrs, byte[] image ) {
    this.orderRepository = orderRepository;
    this.imageUtils = imageUtils;

    // This uses the orderRepository to do some voodoo based on the SpecialOrderAttributes
    SpecialOrderStrategy specialOrderStrategy = new SpecialOrderStrategy( orderRepository );
    specialOrderStrategy.handleAttributes( attrs );

    this.coupon = coupon;
    this.image = image;

    validationUtils.validate( this );
  }

  @PostPersist
  public void postPersist() {
    if( imageUtils != null ) imageUtils.handleImageUpload( image, id, ImageType.Order );
  }
}

1 个答案:

答案 0 :(得分:1)

您正在寻找的是一个扮演协调角色的域服务,它取决于上述服务/存储库。由于对不变量的真实含义的扭曲视图,尝试将过多的责任投入到聚合中是一个经典的错误。后期处理可能会从域事件中受益(无论是在进程内还是在进程外 - 你给我的内容太少,无法继续)。您还可能希望从外部分配标识符,或者在域服务的方法执行中分配一个标识符。至于验证,抛弃属性和手卷(如果它们真的是关于实体)。 YMMV。