问题涉及在实体中注入存储库和实用程序类。
背景
实体不直接使用存储库,而是将其传递给需要强制执行某些业务规则的策略。
有问题的实用程序类有助于验证模型和图像处理功能。验证实用程序将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 );
}
}
答案 0 :(得分:1)
您正在寻找的是一个扮演协调角色的域服务,它取决于上述服务/存储库。由于对不变量的真实含义的扭曲视图,尝试将过多的责任投入到聚合中是一个经典的错误。后期处理可能会从域事件中受益(无论是在进程内还是在进程外 - 你给我的内容太少,无法继续)。您还可能希望从外部分配标识符,或者在域服务的方法执行中分配一个标识符。至于验证,抛弃属性和手卷(如果它们真的是关于实体)。 YMMV。