请查看以下存储库。是否可以使用DDD规则,该存储库会注入一些依赖项并引发事件?我读到该存储库通常属于infrastracture,不应该做这样的事情。您如何看待这种方法? 也许最好在域服务中包装存储库调用并执行事件源和依赖注入? :
public class JpaOrderRepository implements OrderRepository{
@Inject
Private RebatePolicyFactory rebatePolicyFactory;
@Inject
Private InjectorHelper injector;
@Inject
DomainEventPublisher eventPublisher;
public void persist(Order order) {
super.persist(order);
eventPublisher.publish(new OrderCreatedEvent(order.getEntityId())); // !! **Events**
}
Public Order load(OderId orderId) {
Order order = super.load(orderId);
injector.injectDependencies(order);
order.setRebatePolicy(rebatePolicyFactory.createRebatePolicy()); // !! **Dependencies**
return order;
}
}
答案 0 :(得分:1)
Repository是一种DDD模式,它声明您希望抽象行为像伪集合,以封装更改数据的操作。您只应在更改数据之前使用存储库加载数据。
类似的东西:
public class AnApplicationService
{
public void addItemToOrder(orderId, item)
{
Order order = repo.load = (orderId);
order.AddItem(item); // You could publish the event inside AddItem if you prefered
repo.persist(order);
eventPublisher.publish(new ItemAddedToOrderEvent(orderId));
}
}
如果您需要检索订单,因为您想向用户显示有关订单的信息,但您不需要修改订单,则不应使用存储库模式。你需要使用别的东西。
public class AnApplicationService
{
public ReadOnlyOrder GetOrder(orderId)
{
ReadOnlyOrder order = finder.findReadOnlyOrderById(orderId);
/* You could put those 3 lines inside your finder.findReadOnlyOrderById implementation if you prefer */
injector.injectDependencies(order);
order.setRebatePolicy(rebatePolicyFactory.createRebatePolicy());
return order;
}
}
否则,我认为你没有使用足够的抽象。在您的Core中,您需要所有存储库,finder和eventPublisher的接口。
public interface IOrderRepository
{
void persist(Order order);
Order load(OrderId orderId);
}
public interface IFinder
{
ReadOnlyOrder findReadOnlyOrderById(OrderId orderId);
}
public interface IEventPublisher
{
void publish(IEvent event);
}
现在,在您的基础结构中,您可以创建扩展这些接口的具体类。您可以自由地使这些依赖于DI方式,并让他们发布事件。但代码的其他地方应该使用接口,而不是这些具体的实现。同样,你的repo应该注入一个IEventPublisher和一个IRebatePolicySetter,这样它依赖于抽象,而不是实现。
public interface IRebatePolicySetter
{
void setPolicyOnOrder(Order order);
}
public class RebatePolicySetter implements IRebatePolicySetter
{
@Inject
Private RebatePolicyFactory rebatePolicyFactory;
@Inject
Private InjectorHelper injector;
void setPolicyOnOrder(Order order)
{
injector.injectDependencies(order);
order.setRebatePolicy(rebatePolicyFactory.createRebatePolicy());
}
}
public class JpaOrderRepository implements OrderRepository, IOrderRepository
{
@Inject
Private IRebatePolicySetter rebatePolicySetter;
@Inject
IEventPublisher eventPublisher;
public void persist(Order order)
{
super.persist(order);
eventPublisher.publish(new OrderCreatedEvent(order.getEntityId())); // This is ok in my book, as long as eventPublisher is an interface.
}
Public Order load(OderId orderId)
{
Order order = super.load(orderId);
rebatePolicySetter.setPolicyOnOrder(order);
return order;
}
}
话虽如此,在基础架构代码中,您可以拥有任意数量的依赖项。你可能不应该,并试图尽可能地限制它们,这就是我在这里所做的。但是如果回购需要这些东西来执行它的工作,那么在你的回购中注入依赖关系是没问题的。你不希望你的业务逻辑依赖于事物,所以你让他们使用接口。
但请记住
注意:您的persist方法似乎只进行创建添加。如果您也将它用于更新,那么您的OrderCreatedEvent是否会令人困惑?
注意2:为什么RebatePolicy来自工厂?难道订单的折扣政策的信息不是来自持久层吗?