3

최근에 필자는 아키텍처의 일부 기능이 좋은 위치에 있는지 알아 내려고 애썼다. 올바른 레이어에. the repository pattern of Martin Fowler을 따라 데이터베이스에서 내 서비스 계층을 분리하려고합니다.스칼라 값을 검색하기위한 도메인 객체가없는 저장소 패턴

자신의 웹 사이트에 마틴 파울러에 의해 설명 정의는 말 :

저장소는 메모리 도메인 개체 모음처럼 행동, 도메인 및 데이터 매핑 층 사이 을 매개.

문제점은 내가 모든 송장의 합계를 가져야하는 많은 요구 사항이 있다는 것입니다. 이해할 수 있듯이 모든 송장의 합계는 스칼라 값입니다. Martin Fowler의 정의를 따른다면, 내가해야할 일은 서비스 레이어가받는 저장소 레이어의 도메인 개체 목록을 반환하는 함수를 만드는 것입니다.이 도메인은 루프를 계산하여 개체를 계산합니다. 이 패턴이 의미하는 것의 본질을 이해하지 못하는 것도 가능합니다 ...

유지 관리가 더 좋기 때문에 성능을 중요시하지 않아도되지만 내 경우에는 성능이 중요하지 않습니다. 개발 및 성능에있어 시간 낭비가 전혀 없음 은 청구서 합계에 해당하는 10 진수 값을 반환하고이 동일한 값을 서비스 계층에서 반환하는 저장소 계층의 함수를 만들지 않습니다. ORM과 함께 게으른 로딩 전략을 추가 할 수있는 경우라도 개체 목록을 구체화 한 다음 단일 속성을 사용하는 것은 잔인합니다.

리포지토리 계층에서 스칼라 값을 반환하는 것이 맞습니까? 아니면 유혹에 저항해야하며 항상이 계층에서 도메인 개체를 반환하고 서비스 계층의 모든 비즈니스 논리를 처리해야합니까?

내 발표자가 저장소 계층을 호출하는 대신 서비스 계층을 호출하는 대신 내 저장소를 직접 호출하는 곳이 많습니다. 그것은 정확하다; 이 저장소 패턴을 서비스 계층 외부에서 호출 할 수 있습니까?

내 저장소 계층에서 IQueryable 결과를 반환하지 않으려는데, 이는 Law of Demeter과 완전히 모순이 될 수 있기 때문입니다.

또한이 계층을 완전히 단위 테스트 할 수 있기를 원하기 때문에 내 서비스 계층에서 직접 쿼리를 설정하고 싶지는 않습니다. 통합 테스트를하지 않습니다.

+0

스칼라 값을 반환해도 문제가 없습니다. UI에서 리포지토리를 호출하는 것은 일부 상황 (예 : 콤보 상자 채우기)에서 정확합니다. 표시되기 전에 처리되지 않았 으면 좋습니다. 그것은 단지 내 의견이지만 – Mathieu

답변

1

비슷한 문제가 있었는데 기본 저장소 인터페이스를 파생 시켰습니다. 기본 메소드에는 가져 오기, 업데이트 등의 표준 메소드가 있지만 파생 인터페이스에는 특정 메소드 (사용자의 경우 스칼라 값 가져 오기)가 있습니다. 그런 다음 인터페이스를 구현하는 InvoiceRepository 클래스를 만들

public interface IInvoiceRepository : IRepository 
{ 
    int GetTotal(); 
} 

public interface IRepository { ... } 

. 비즈니스 로직을 별도의 클래스로 구현하는 것이 더 낫습니다. InvoiceBusinessObject는 IInvoiceRepository 유형의 종속성 주입을 가져옵니다 (생성자에서 매개 변수 사용). 비즈니스 계층에서 구현을 사용하지 마십시오.

public class InvoiceBusinessObject 
{ 
    private IInvoiceRepository rep; 

    public InvoiceBusinessObject(IInvoiceRepository rep) 
    { 
    this.rep = rep; 
    } 

    public int GetTotal() 
    { 
    return rep.GetTotal(); 
    } 
} 

서비스 계층은 InvoiceRepository 클래스를 인스턴스화하고 비즈니스 오브젝트 클래스로 인스턴스를 삽입 할 수

public int GetTotalFromService() 
{ 
    IInvoiceRepository rep = new InvoiceRepository(); 
    InvoiceBusinessObject bizObj = new InvoiceBusinessObject(rep); 
    return bizObj.GetTotal(); 
} 
+0

이 방법은 매우 복잡한 IMO처럼 보입니다. 그리고 나는 비즈니스 오브젝트가 저장소를 숨기는 것이 적절하지 않다고 생각합니다. – MikeSW

2

문제가 쉽게 (개념으로) CQRS으로 해결된다. UI (또는 MVC를 사용할 때 컨트롤러가 사용할 수있는 전용 쿼리 전용 리포지토리가 있어야합니다. 이 레포는 db (ORM 엔티티는 실제로 중요하지 않음)를 직접 쿼리하여 필요한 것을 반환 할 수 있습니다.

는 '무거운'도메인 객체와 모델을 업데이트 할 때 만 해당 저장소를 유지합니다.