저장소 인 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;
}
}
그렇지 않으면 충분한 추상화로 작업하지 않는 것 같습니다. 코어에서 모든 저장소, 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;
}
}
인프라 코드에서 원하는만큼의 종속성을 가질 수 있습니다. 당신은 아마 내가 그 일을 가능한 한 많이 제한해서는 안되며, 그렇게하려고해서는 안됩니다. repo가 작업을 수행하기 위해 이러한 것들을 필요로한다면 Repo에 의존성을 주입하는 것이 좋습니다. 비즈니스 논리가 사물에 의존하는 것을 원하지 않으므로 인터페이스를 사용해야합니다.
참고 : persist 메서드는 생성 만 추가하는 것처럼 보입니다. 업데이트 용으로도 사용한다면 OrderCreatedEvent가 혼란스럽지 않습니까?
참고 2 : Rebate 정책은 왜 공장에서 나옵니까? 순서의 리베이트 정책에 대한 정보가 영구적 인 레이어에서 나오지 않아야합니까?
리포지토리는 도메인 계층에 속하며 해당 구현은 인프라 계층에 속합니다. 나는 이것이 좋은 것이라고 생각한다. 그러나 대개 모델에 종속성을 주입하는 것은 권장되지 않습니다. – Hippoom
예 인터페이스는 도메인에 속하며 인프라 스트럭처로 구현됩니다. DI는 권장하지 않습니다. 이벤트 소싱은 어떻게됩니까? – dpolaczanski
DDD의 모든 부분에서 벗어나고 있다고 생각합니다. 귀하의 질문에 구현이 있지만 요구 사항은 없습니다. 해결하려는 비즈니스 문제는 무엇입니까? –