我一直在探索 BDD/DDD,因此试图提出存储库模式的正确实现。到目前为止,很难就实现这一点的最佳方式达成共识。我试图将其归结为以下变体,但我不确定哪种方法是最好的。
作为参考,我正在构建一个以 NHibernate 作为后端的 ASP.MVC 应用程序。
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);
}
我最初的想法是
1)从效率的角度来看很好,但是随着事情变得更加复杂,我可能会遇到麻烦。
2) 看起来很乏味,最终可能会出现一个非常拥挤的课程,但否则会在我喜欢的领域逻辑和数据层之间提供高度分离。
3) 似乎很难预先编写查询并且需要更多的工作来编写查询,但是将交叉污染限制在 Specs 层。
4) 我最不喜欢,但可能是最直接的实现,并且对于复杂的查询可能是最高效的数据库,尽管它给调用代码带来了很多责任。