저에게 ORM 또는 다른 DB 지속성 계층과 결합 된 리포지토리에는 다음과 같은 단점이 있습니다.
- 작업 단위를 커버. UoW는 프로그래머가 코딩해야하며 백그라운드에서 일종의 마술로 구현되는 경우는 거의 없습니다. 사용자는 UoW 경계 및 커밋 지점을 정의하지 않고 단순히 쿼리 및 수정을 수행합니다. 때로는 각 리포지토리 액세스 방법에서 UoW를 마이크로 UoW (예 : NHibernate 세션)로 줄여서 포기합니다.
- 지속성 무지 (Current Pergistence Ignorance)를 덮거나 최악의 경우 : "Load ()", "Get ()", "Save ()"또는 "Update ()"와 같은 메서드는 개별 개체를 보내는 것처럼 즉각적인 단일 개체 작업을 제안합니다 SQL / DML 또는 파일로 작업하는 것처럼. 실제로, 예를 들어, 이러한 잘못된 이름을 가진 NHibernate 메소드는 일반적으로 개별 액세스를하지 않지만 지연로드 또는 삽입 / 업데이트 배치 (지속성 무지)를 위해 대기합니다. 때때로 프로그래머는 왜 즉각적인 DB 작업을 수행하지 않고 지속성 무지를 강제로 중단하여 성능을 저하시키고 실제로 시스템을 악화시키기 위해 많은 노력을 기울입니다.
- 통제되지 않은 성장. 간단한 저장소는 특정 요구에 맞게 점점 더 많은 방법을 축적 할 수 있습니다.
같은 :
public interface ICarsRepository /* initial */
{
ICar CreateNewCar();
ICar LoadCar(int id); // bad, should be for multiple IDs.
void SaveCar(ICar carToSave); // bad, no individual saves, use UoW commit!
}
public interface ICarsRepository /* a few years later */
{
ICar CreateNewCar();
ICar LoadCar(int id);
IList<ICar> GetBlueCars();
IList<ICar> GetRedYellowGreenCars();
IList<ICar> GetCarsByColor(Color colorOfCars); // a bit better
IList<ICar> GetCarsByColor(IEnumerable<Color> colorsOfCars); // better!
IList<ICar> GetCarsWithPowerBetween(int hpFrom, int hpTo);
IList<ICar> GetCarsWithPowerKwBetween(int kwFrom, int kwTo);
IList<ICar> GetCarsBuiltBetween(int yearFrom, int yearTo);
IList<ICar> GetCarsBuiltBetween(DateTime from, DateTime to); // some also need month and day
IList<ICar> GetHybridCarsBuiltBetween(DateTime from, DateTime to);
IList<ICar> GetElectricCarsBuiltBetween(DateTime from, DateTime to);
IList<ICar> GetCarsFromManufacturer(IManufacturer carManufacturer);
bool HasCarMeanwhileBeenChangedBySomebodyElseInDb(ICar car); // persistence ignorance broken
void SaveCar(ICar carToSave);
}
4. 신의 위험 개체 : 모든 모델 또는 데이터 액세스 계층을 포함하는 하나의 신 클래스를 만들려고 할 수 있습니다. 저장소 클래스는 Car 메소드뿐만 아니라 모든 엔티티에 대한 메소드를 포함합니다.
내 의견으로는, 많은 단일 목적 방법의 큰 혼란을 피하기 위해 적어도 쿼리 기회를 제공하는 것이 좋습니다. 그것이 LINQ이든, 자체 쿼리 언어이거나 ORM에서 직접 가져온 것 (OK, kind of coupling problem ...)이든 상관 없습니다.