그들은 같은 것입니까? Rob Connery의 Storefront 튜토리얼 시청을 마쳤으며 유사한 기술인 것 같습니다. 즉, DAL 개체를 구현할 때 GetStuff, Add / Delete 등 메서드가 있고 나중에 db를 전환 할 수 있도록 항상 인터페이스를 먼저 작성합니다.
내가 헷갈 리나요?
그들은 같은 것입니까? 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입니까, 리포지토리입니까? 이 경우에는 둘 다 추측합니다.
김
한 가지 큰 차이점은 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에서 무엇이든 될 수있는 도메인 개체입니다. 저에게는 중요한 추가 / 제한 사항입니다. 다른 레이아웃으로 데이터베이스 / 서비스에 대한 리포지토리 구현을 추가 할 수 있고 매핑에 집중할 수있는 명확한 위치가 있기 때문입니다. 이 제한을 사용하지 않고 다른 곳에 매핑을하는 경우 데이터를 표현하는 다른 방법을 사용하면 변경해서는 안되는 위치의 코드에 영향을 미칠 수 있습니다.
리포지토리 패턴 사용의 장점은 DAL 코드를 호출하지 않고도 비즈니스 계층 코드를 테스트 할 수 있도록 데이터 액세스 계층을 모의하는 것입니다. 다른 큰 장점이 있지만 이것은 나에게 매우 중요한 것 같습니다.
그래서 대부분의 (간단한) 경우 DAO는 Repository의 구현입니까?
내가 이해하는 한, DAO는 db 액세스 (CRUD-No selects ?!)를 정확하게 처리하는 반면 Repository를 사용하면 전체 데이터 액세스를 추상화 할 수 있습니다.
나는 올바른 길을 가고 있는가?
외부 세계 (예 : 클라이언트 코드)에서 저장소는 다음을 제외하고 DAL과 동일합니다.
(1) 삽입 / 업데이트 / 삭제 방법은 데이터 컨테이너 개체를 매개 변수로 사용하도록 제한됩니다.
(2) 읽기 작업의 경우 DAL (예 : GetByPK) 또는 고급 사양과 같은 간단한 사양이 필요할 수 있습니다.
내부적으로 데이터 매퍼 레이어 (예 : 엔터티 프레임 워크 컨텍스트 등)와 함께 작동하여 실제 CRUD 작업을 수행합니다.
리포지토리 패턴이 의미하지 않는 것 :-
또한 삽입 / 업데이트 / 삭제 메서드가 수행 한 모든 메모리 내 변경 사항을 데이터베이스에 커밋하는 Insert / Update / Delete 메서드 외에 리포지토리 패턴 샘플 구현으로 별도의 Save 메서드를 사용하는 것에 대해 사람들이 종종 혼동하는 것을 보았습니다. 우리는 저장소에 저장 방법을 확실히 가질 수 있지만 메모리 내 CUD (생성, 업데이트, 삭제) 및 지속성 방법 (데이터베이스에서 실제 쓰기 / 변경 작업을 수행)을 격리하는 저장소의 책임은 아니지만 작업 단위 패턴의 책임.
도움이 되었기를 바랍니다!