【Yom框架】漫談個人框架的設計之一:是IRepository還是IRepository


前言                                                                                                                 

對於倉儲Repository的設計,其實很多人都很糾結,因為從廣義來說,Repository有兩種類型:

IRepositoryIRepository<T>

框架的重構想得最多的最重要的幾個問題:

1:解耦(每層可以替換其他的,比如換一個UI層可以把Web 項目快速轉換成Winform項目)

2:擴展性(可以靈活抹去框架的某個層,讓其他的第三方框架依據自己的接口實現該層的邏輯,其它層不變,也就是插拔式擴展)

3:靈活(開發便捷,使用靈活)

4:維護性(別人了解框架后,可以讓別人無障礙維護)

........

-------------------------------------

題外話不多說 馬上進入辯證主題:是IRepository還是IRepository<T>

------------------------------------

首先看IRepository<T>                                                                   

IRepository<T>接口定義形式如下(其中IEntity是一個實體類接口):

 1 public interface IRepository<T> where T : Entity.IEntity
 2     {
 3         T FindBy(string primaryKey);
 4         IEnumerable<T> FindAll();
 5         IEnumerable<T> FindAll(string where);
 6         IEnumerable<T> FindAll(string where, string order);
 7         IEnumerable<T> FindAll(int pageIndex, int pageSize, string where, string order, out int count);
 8         void Add(T entity);
 9         void Delete(T entity);
10         void DeleteAll();
11         void DeleteAll(string where);
12         void DeleteAll(System.Collections.IEnumerable pkValues);
13         void Update(T entity);
14         bool Exists(string primaryKey);
15     }

可以看見,IRepository和接口IEntity通過泛型T結合在了一起,形成了耦合

IRepository<T> 可以通過T操作IEntity

開發的時候,每個IEntity的子類都得對應一個IRepository<T>的子類,如:

public class DepartmentRepository :  Repository.RepositoryBase<Entity.Department.Department>
    {
    }

其中Department是IEntity的一個子類

而RepositoryBase<T>是一個真正可用的倉儲父類(此類已通過第三方或者自己的ORM框架實現了數據庫操作)

------------------------------------

再看IRepository接口                                                                                

------------------------------------

IRepository接口的設計:

public interface IRepository
    {
        #region 實體相關接口 
        TEntity FindBy<TEntity>(IEnumerable<string> primaryKey)
            where TEntity : IEntity;

        IEnumerable<TEntity> FindAll<TEntity>() where TEntity : IEntity;

        IEnumerable<TEntity> FindAll<TEntity>(string where, params System.Data.IDataParameter[] ps) where TEntity : IEntity;

        IEnumerable<TEntity> FindAll<TEntity>(string where, string order, params System.Data.IDataParameter[] ps) where TEntity : IEntity;

        IEnumerable<TEntity> FindAll<TEntity>(int pageIndex, int pageSize, string where, string order, out int count, params System.Data.IDataParameter[] ps) where TEntity : IEntity;

        void Add<TEntity>(TEntity entity) where TEntity : IEntity;

        void Delete<TEntity>(TEntity entity) where TEntity : IEntity;

        void DeleteAll<TEntity>() where TEntity : IEntity;

        void DeleteAll<TEntity>(string where, params System.Data.IDataParameter[] ps) where TEntity : IEntity;

        void DeleteAll<TEntity>(IEnumerable<IEnumerable<string>> pkValues)
            where TEntity : IEntity;

        void Update<TEntity>(TEntity entity) where TEntity : IEntity;

        bool Exists<TEntity>(IEnumerable<string> primaryKey)
            where TEntity : IEntity;

        #endregion
        #region 原始數據操作接口

        int ExecuteSql(string sql, params System.Data.IDataParameter[] ps);

        object ExecuteScalar(string sql, params System.Data.IDataParameter[] ps);

        System.Data.DataTable ExecuteDataTable(string sql, params System.Data.IDataParameter[] ps);
        #endregion
    }

 

這種接口的設計就是把IReopository<T>里的T放入接口的方法中,

讓泛型方法操作對應的帶入泛型實體類

IReopository接口的設計可以很好地實現Repository共用

也就是說整個項目只要一個通過ORM實現了的RepositoryBase類就可以操作所有的持久層實體對象

不用每個實體類都對應一個Repository

大大的減少了項目開發的繁雜性

對於業務邏輯,新增一個Server層讓每個Server類對應一個實體類的邏輯

如:假設有Class Aa 則必須有 Class AaServer對應

而Server就調用RepositoryBase類操作Server類對應的實體

--------------------------------------

總結:                                                                                                                     

其實不管是IRepository還是IRepository<T> 都各自有各自的優勢:

1、IRepository<T>的子類對實體類是很專注的,它只可以操作一個實體類,對IRepository<T>的子類的修改不會影響到其他實體類的操作

從而可以實現對應實體類的個性化拓展;

2、IRepository可以操作所有的實體類,修改IRepository的子類則會影響所有的實體的操作

雖然如此,在開發過程中,難免會有在某個業務層XxServer操作其他實體類的需要

如果是用IRepository<T>倉儲,那么必須在業務層XxServer中New很多其他實體類對應的IRepository<T>的子類對象出來

這對於Repository與Server的解耦是個大忌,也就是說Repository層和Server層已經高度耦合了。

也正因為這個原因我個人更傾向於IRepository,並拋棄Repository層(如果是每個實體對應一個Repository,那么將需要一個Repository層),

只讓一個可以操作所有所有實體的Repository存在就可以了

更重要的原因是Repository層相對來說,接口比較穩定,一般的項目,沒有要擴展IRepository接口操作的需要。

 所以IRepository接口一個重要的優勢是:

在某個實體類的Server層可以統一用IRepository類的方法實現業務,

不需要像IRepository<T>實現方式一樣,New額外的對象就才可以操作其他實體類,

只要在【Repository.方法<T>】里的T換成其他實體類就可以了

這對解耦來說是有好處的。

所以正是因為這個原因,我選擇IRepository,而不是IRepository<T>

---------------------

題外話                                                                                                   

上面的IRepository接口已經被我再次拋棄了

拋棄原因如下:

1:接口的組合主鍵擴展性差,也就是說主鍵會受制於ORM框架的實現

2:不支持搜索和排序解耦

 

至於新的IRepository接口 將在下篇文章給出

-------------------------------------

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM