在Repository Pattern中必须创建多少存储库接口?

时间:2015-07-02 11:43:16

标签: java c# design-patterns repository-pattern

假设我们有以下课程:

public class User
{
    //User Definitions Goes Here
}

public class Product
{
    //Product Definitions Goes Here
}

public class Order
{
    //Order Definitions Goes Here
}

拥有以上模型,我应该只创建一个存储库,如:

public interface IRepository
{
    //IRepository Definition Goes Here
}

或者最好有多个存储库:

public interface IUserRepository
{
    //IUserRepository Definition Goes Here
}

public interface IProductRepository
{
    //IProductRepository Definition Goes Here
}

public interface IOrderRepository
{
    //IOrderRepository Definition Goes Here
}

每个优点和缺点是什么?

2 个答案:

答案 0 :(得分:2)

没有必须。您可以创建尽可能多的应用程序需求。您可以为每个业务对象和通用接口创建存储库接口。

这样的东西
interface ICRUDRepo<T> //where T is always a Domain object
{
    T get(GUid id);
    void Add(T entity);
    void Save(T entity);
 }

//then it's best (for maintainability) to define a specific interface for each case

interface IProductsRepository:ICRUDRepo<Product>
{
    //additional methods if needed by the domain use cases only

    //this search the storage for Products matching a certain criteria,
    // then returns a materialized collection of products 
    //which satisfy the given criteria
    IEnumerable<Product> GetProducts(SelectByDate criteria);
 }

这是关于拥有一个干净清晰的抽象,这将允许域与持久性正确解耦。

通用抽象是存在的,因此我们保存了几个键击,可能有一些常见的扩展方法。但是,为这些目的使用通用通用接口并不真正算作DRY

答案 1 :(得分:1)

如果采用第一种方法,则应避免重复自己,满足DRY原则。但是,您可以通过将未连接的项目集中在一个接口和任何实现类中来打破关注点分离原则。

如果你采用第二种方法,你可以实现良好的关注点分离,但有可能重复自己,从而违反DRY原则。

一种解决方案是第三种方式:混合物。

public interface IRepository<T>
{
    IEnumerable<T> Query {get;}
    void Add(TEntity entity);
    void Delete(TEntity entity);
}

public interface IUserRepository : IRepository<IUser>;
public interface IProductRepository : IRepository<IProduct>;
public interface IOrderRepository : IRepository<IOrder>;

这种方法满足了这两个原则。