2014-04-14 2 views
0

다음 저장소를 확인하십시오. DDD 규칙은 괜찮습니까? 저장소가 일부 종속성을 주입하고 이벤트를 발생시킵니다. 저장소가 일반적으로 인프라 스트럭처에 속하며 이와 같은 일을해서는 안된다는 것을 읽었습니다. 이 접근법에 대해 어떻게 생각하십니까? 도메인 서비스에서 저장소 호출을 래핑하는 것이 더 좋을 수 있으며 이벤트 소싱 및 종속 주입을 수행 할 수 있습니까? :저장소를 발생시키는 이벤트 및 주입 종속성

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; 
} 


} 

https://code.google.com/p/ddd-cqrs-sample/source/browse/branches/ddd_cqrs-sample/jee/src/main/java/pl/com/bottega/erp/sales/infrastructure/repositories/jpa/JpaOrderRepository.java?r=190

+0

리포지토리는 도메인 계층에 속하며 해당 구현은 인프라 계층에 속합니다. 나는 이것이 좋은 것이라고 생각한다. 그러나 대개 모델에 종속성을 주입하는 것은 권장되지 않습니다. – Hippoom

+0

예 인터페이스는 도메인에 속하며 인프라 스트럭처로 구현됩니다. DI는 권장하지 않습니다. 이벤트 소싱은 어떻게됩니까? – dpolaczanski

+0

DDD의 모든 부분에서 벗어나고 있다고 생각합니다. 귀하의 질문에 구현이 있지만 요구 사항은 없습니다. 해결하려는 비즈니스 문제는 무엇입니까? –

답변

1

저장소 인 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 정책은 왜 공장에서 나옵니까? 순서의 리베이트 정책에 대한 정보가 영구적 인 레이어에서 나오지 않아야합니까?