[asp.net-mvc] 리포지토리 패턴 대 DAL

그들은 같은 것입니까? Rob Connery의 Storefront 튜토리얼 시청을 마쳤으며 유사한 기술인 것 같습니다. 즉, DAL 개체를 구현할 때 GetStuff, Add / Delete 등 메서드가 있고 나중에 db를 전환 할 수 있도록 항상 인터페이스를 먼저 작성합니다.

내가 헷갈 리나요?



답변

당신은 확실히 일을 혼동하는 사람이 아닙니다. 🙂

나는 질문에 대한 답은 당신이 얼마나 순수 주의자가되고 싶은지에 달려 있다고 생각합니다.

엄격한 DDD 관점을 원한다면 한 길을 내려갈 것입니다. 리포지토리를 서비스와 데이터베이스를 분리하는 계층의 인터페이스를 표준화하는 데 도움이 된 패턴으로 보면 다른 작업을 중단하게됩니다.

제 관점에서 저장소는 데이터에 대한 액세스의 명확하게 지정된 계층 일뿐입니다. 즉, 데이터 액세스 계층을 구현하는 표준화 된 방법입니다. 저장소 구현에 따라 약간의 차이가 있지만 개념은 동일합니다.

어떤 사람들은 저장소에 더 많은 DDD 제약을 두는 반면 다른 사람들은 데이터베이스와 서비스 계층 사이의 편리한 중재자로서 저장소를 사용할 것입니다. DAL과 같은 리포지토리는 데이터 액세스 세부 사항에서 서비스 계층을 분리합니다.

그것들을 다르게 만드는 것으로 보이는 구현 문제 중 하나는 저장소가 종종 사양을 취하는 메소드로 생성된다는 것입니다. 저장소는 해당 사양을 충족하는 데이터를 반환합니다. 내가 본 대부분의 기존 DAL에는 메서드가 여러 매개 변수를 사용하는 더 큰 메서드 집합이 있습니다. 이것은 작은 차이처럼 들릴지 모르지만 Linq와 Expressions의 영역에 들어가면 큰 문제입니다. 기본 저장소 인터페이스는 다음과 같습니다.

public interface IRepository : IDisposable
{
    T[] GetAll<T>();
    T[] GetAll<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
    void Delete<T>(T entity);
    void Add<T>(T entity);
    int SaveChanges();
    DbTransaction BeginTransaction();
}

DAL입니까, 리포지토리입니까? 이 경우에는 둘 다 추측합니다.


답변

리포지토리는 다양한 방식으로 적용 할 수있는 패턴이지만 데이터 액세스 계층에는 매우 명확한 책임이 있습니다. DAL은 CRUD 작업을 수행하기 위해 데이터 저장소에 연결하는 방법을 알아야합니다.

리포지토리 DAL 있지만 DAL 앞에 배치되어 비즈니스 개체 계층과 데이터 계층 사이의 다리 역할을 할 수도 있습니다. 어떤 구현이 사용되는지는 프로젝트마다 다릅니다.


답변

한 가지 큰 차이점은 DAO는 도메인의 모든 엔티티에 대한 지속성을 처리하는 일반적인 방법이라는 것입니다. 반면에 저장소는 집계 루트 만 처리합니다.


답변

나는 비슷한 질문에 대한 답을 찾고 있었고 가장 높은 두 개의 답변에 동의합니다. 이것을 명확히하기 위해 Repository 패턴과 밀접한 관련이 있는 사양이 도메인 모델의 일급 구성원으로 구현되면

  • 다른 매개 변수로 사양 정의를 재사용합니다 .
  • 기존 사양 인스턴스의 매개 변수 조작 (예 : 전문화)
  • 결합 하고
  • 데이터베이스에 액세스하지 않고도 비즈니스 로직수행 합니다.
  • 물론 실제 리포지토리 구현과 관계없이 단위 테스트를 수행합니다.

난 지금까지와 상태에 있음을 갈 수 없는 한 “저장소”저장소 패턴이 사양 패턴과 함께 사용되는, 정말 아니에요하지만 DAL. 의사 코드의 인위적인 예 :

specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)

assert that specification200.isSpecialCaseOf(specification100)

specificationAge = new AccountIsOlderThan('2000-01-01')

combinedSpec = new CompositeSpecification(
    SpecificationOperator.And, specification200, specificationAge)

for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

자세한 내용은 Fowler의 사양 에세이 를 참조하십시오 (위의 내용을 기반으로 한 것입니다).

DAL에는 다음과 같은 특수한 방법이 있습니다.

IoCManager.InstanceFor<IAccountDAO>()
    .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')

당신은 당신이이 방법으로 DAL / DAO 인터페이스의 각을 정의해야 특히 이후,이 신속 성가신 될 수있는 방법을 볼 수 있습니다 DAL 쿼리 방법을 구현한다.

.NET에서 LINQ 쿼리 사양을 구현하는 한 가지 방법이 될 있지만 사양 (표현식)을 결합하는 것은 자체 개발 한 솔루션만큼 원활하지 않을 수 있습니다. 이에 대한 몇 가지 아이디어는 이 SO 질문에 설명되어 있습니다.


답변

내 개인적인 의견은 매핑에 관한 것입니다. http://www.martinfowler.com/eaaCatalog/repository.html을 참조 하십시오 . 따라서 리포지토리의 출력 / 입력은 DAL에서 무엇이든 될 수있는 도메인 개체입니다. 저에게는 중요한 추가 / 제한 사항입니다. 다른 레이아웃으로 데이터베이스 / 서비스에 대한 리포지토리 구현을 추가 할 수 있고 매핑에 집중할 수있는 명확한 위치가 있기 때문입니다. 이 제한을 사용하지 않고 다른 곳에 매핑을하는 경우 데이터를 표현하는 다른 방법을 사용하면 변경해서는 안되는 위치의 코드에 영향을 미칠 수 있습니다.


답변

해석과 맥락에 관한 것입니다. 그들은 매우 유사하거나 실제로 매우 다를 수 있지만 솔루션이 작동하는 한 이름은 무엇입니까!


답변

리포지토리는 패턴이며, 가능한 한 코드를 재사용 할 수 있도록 표준화 된 방식으로 구현하는 방법입니다.