框架的设计之IRepository还是IRepository<T>
【Yom框架】漫谈个人框架的设计之【是IRepository还是IRepository<T>】?
前言
对于仓储Repository的设计,其实很多人都很纠结,因为从广义来说,Repository有两种类型:
IRepository和IRepository<T>
框架的重构想得最多的最重要的几个问题:
1:解耦(每层可以替换其他的,比如换一个UI层可以把Web 项目快速转换成Winform项目)
2:扩展性(可以灵活抹去框架的某个层,让其他的第三方框架依据自己的接口实现该层的逻辑,其它层不变,也就是插拔式扩展)
3:灵活(开发便捷,使用灵活)
4:维护性(别人了解框架后,可以让别人无障碍维护)
........
-------------------------------------
题外话不多说 马上进入辩证主题:是IRepository还是IRepository<T> ?
------------------------------------
首先看IRepository<T>
IRepository<T>接口定义形式如下(其中IEntiry是一个实体类接口):
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
}
这种接口的设计就是把ReopositoryBase<T>里的T放入接口的方法中,
让泛型方法操作对应的实体类
这种接口的设计可以很好地实现Repository共用
也就是说整个项目只要一个通过ORM实现了的RepositoryBase类就可以操作所有的持久层实体对象
不用每个实体类都对应一个IRepository
大大的减少了项目开发的便捷性
对于业务逻辑,新增一个Server层
Server层,让每个Server类对应一个实体类的逻辑,如:假设有Class Aa 则必须有 Class AaServer对应
而Server就调用RepositoryBase类操作Server类对应的实体
--------------------------------------
总结:
其实不管是IRepository还是IRepository<T> 都各自有各自的优势
IRepository<T>的子类对实体类是很专注的,它只可以操作一个实体类,对它的修改不会影响到其他实体来的操作
从而可以实现对应实体类的个性化拓展,而IRepository可以操作所有的实体类,修改了子类则会影响所有的实体的操作
虽然如此,在开发过程中,难免会有在某个业务层操作其他对象的需要
如果是IRepository<T>,那么必须在业务层New很多其他实体类对应的IRepository<T>子类对象出来
这对于解耦是个大忌,也就是说Repository层和Server层已经高度耦合了。
也正因为这个原因我个人更倾向于IRepository,抛弃Repository层,只让一个可以操作所有所有实体的Repository存在就可以了
更重要的原因是Repository层相对拉来说,接口比较稳定,一般的项目,没有必要扩展IRepository接口的操作。
所以IRepository接口一个重要的优势是:
在某个实体类的Server层可以用IRepository类的方法,不需要New额外的对象就可以操作其他实体类,
只要在【Repository.方法<T>】里的T换成其他实体类就可以了
如果换成IRepository<T>实现,则需要在该实体类的Server层New很多其他实体类对应的IRepository<T>才可以操作其他实体类的对象,这对解耦来说是大忌。所以正是因为这个原因,我宁愿选择IRepository,而不是IRepository<T>
---------------------
题外话
上面的IRepository接口已经被我再次抛弃了
抛弃原因如下:
1:接口的组合主键扩展性差,也就是说主键会受制于ORM框架的实现
2:不支持搜索和排序解耦
所以建议自己好好设计IRepository接口
-------------------------------------
完
最新文章
- Intelij IDEA解决Dependency无法更新问题
- Skyline6.5系列覆盖三维地理信息产业上下游
- javascript中单体模式的实现
- ubuntu中安装Rstdio无法切换中文输入法
- GDB调试方法精粹
- [King.yue]Ext.net 页面布局Flex
- 【HDOJ】3466 Proud Merchants
- PHP 获取时间的各种处理方式!
- N皇后( DFS,推荐)
- 藏地传奇js
- DNA序列局部比对(Smith–Waterman algorithm)
- 使用VIM将文件的其中的连续几行注释删除或者给其中的连续几行添加注释
- Django extra 和 annotate
- Android 数据库框架ormlite
- IdentityServer4支持的授权类型以及组合
- MQTT详解以及在IoT中的应用
- Windows下安装pymssql
- PowerDesigner16工具学习笔记-工具介绍
- Redis在Windows+linux平台下的安装配置(转)
- SpringBoot访问html访问不了的问题
热门文章
- 【百度地图API】交你如何用百度地图搜索自己的数据!不需数据库!
- android ListView之BaseAdapter的使用方式
- .net mvc4 从客户端中检测到有潜在危险的 Request.Form 值
- 我的MYSQL学习心得(九)
- Equals 和==
- Facebook HHVM 和 Hack 手册 --- 2. HHVM能做什么
- hibernate之使用Annotation注解搭建项目
- sessionStorage、localStorage、cookie
- Android Studio非gradleproject编译后的apk文件在哪?
- xheditor 进阶