Badałem BDD/DDD i w konsekwencji starałem się wymyślić właściwą implementację wzorca repozytorium. Do tej pory trudno było osiągnąć konsensus co do najlepszego sposobu wdrożenia tego. Próbowałem sprowadzić to do następujących odmian, ale nie jestem pewien, które podejście jest najlepsze.Najlepszy sposób na wdrożenie wzoru repozytorium?
Dla odniesienia buduję aplikację ASP.MVC z NHibernate jako back-end.
public interface IRepository<T> {
// 1) Thin facade over LINQ
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IQueryable<T> Find();
// or possibly even
T Get(Expression<Func<T, bool>> query);
List<T> Find(Expression<Func<T, bool>> query);
}
public interface IRepository<T> {
// 2) Custom methods for each query
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IList<T> FindAll();
IList<T> FindBySku(string sku);
IList<T> FindByName(string name);
IList<T> FindByPrice(decimal price);
// ... and so on
}
public interface IRepository<T> {
// 3) Wrap NHibernate Criteria in Spec pattern
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IList<T> FindAll();
IList<T> FindBySpec(ISpecification<T> specification);
T GetById(int id);
}
public interface IRepository<T> {
// 4) Expose NHibernate Criteria directly
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IList<T> FindAll();
IList<T> Find(ICriteria criteria);
// .. or possibly
IList<T> Find(HQL stuff);
}
Moje pierwsze myśli, które
1) jest świetny z punktu widzenia efektywności, ale mogę mieć kłopoty, jak robi się bardziej skomplikowana.
2) wydaje się bardzo żmudna i może zakończyć się bardzo zatłoczoną klasą, ale poza tym oferuje wysoki stopień separacji między moją logiką domeny i warstwą danych, które lubię.
3) wydaje się trudne z góry i więcej pracy, aby pisać zapytania, ale ogranicza krzyżowanie zanieczyszczeń tylko do warstwy Specs.
4) Moja najmniej ulubiona, ale prawdopodobnie najbardziej bezpośrednia implementacja i prawdopodobnie najbardziej wydajna baza danych dla złożonych zapytań, jednak nakłada dużą odpowiedzialność na kod wywołujący.
+1 za aktualne pytanie. Zmagałem się również ze schematem repozytorium. – TrueWill
Prawdopodobnie nie to, czego szukasz, ale stwierdziłem, że ta implementacja wzoru Spec naprawdę jest fajna: http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using.html. Głównie dlatego, że pozwala używać Linq2Sql/Linq2NHibernate/etc. –
Dzięki TrueWill i dzięki Martinho, które bardzo dobrze odnoszą się do innego tematu, który niedawno opublikowałem http: // stackoverflow.com/questions/1408553/specyfikacja-wzór-kontra-spec-in-bdd –