【Yom框架】漫谈个人框架的设计之一:是IRepository还是IRepository<T>?
前言
对于仓储Repository的设计,其实很多人都很纠结,因为从广义来说,Repository有两种类型:
IRepository和IRepository<T>
框架的重构想得最多的最重要的几个问题:
1:解耦(每层可以替换其他的,比如换一个UI层可以把Web 项目快速转换成Winform项目)
2:扩展性(可以灵活抹去框架的某个层,让其他的第三方框架依据自己的接口实现该层的逻辑,其它层不变,也就是插拔式扩展)
3:灵活(开发便捷,使用灵活)
4:维护性(别人了解框架后,可以让别人无障碍维护)
........
-------------------------------------
题外话不多说 马上进入辩证主题:是IRepository还是IRepository<T> ?
------------------------------------
首先看IRepository<T>
IRepository<T>接口定义形式如下(其中IEntity是一个实体类接口):
public interface IRepository<T> where T : Entity.IEntity
{
T FindBy(string primaryKey);
IEnumerable<T> FindAll();
IEnumerable<T> FindAll(string where);
IEnumerable<T> FindAll(string where, string order);
IEnumerable<T> FindAll(int pageIndex, int pageSize, string where, string order, out int count);
void Add(T entity);
void Delete(T entity);
void DeleteAll();
void DeleteAll(string where);
void DeleteAll(System.Collections.IEnumerable pkValues);
void Update(T entity);
bool Exists(string primaryKey);
}
可以看见,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接口 将在下篇文章给出
-------------------------------------
完
【Yom框架】漫谈个人框架的设计之一:是IRepository还是IRepository<T>?的更多相关文章
- 【Yom框架】漫谈个人框架的设计之三:业务接口+UI层的设计(基于Castle实现的Repository)
Repository层设计的文章见:[http://www.cnblogs.com/yomho/p/3297042.html] 一.概要设计 上面Reposity 应该为 Repository 特 ...
- 【Yom框架】漫谈个人框架的设计之二:新的IRepository接口+搜索和排序解耦(+基于Castle实现)
经过了上篇IRepository和IRepository<T>的讨论[文章地址为:http://www.cnblogs.com/yomho/p/3296759.html] 我选择了IRep ...
- 框架的设计之IRepository还是IRepository<T>
[Yom框架]漫谈个人框架的设计之[是IRepository还是IRepository<T>]? 前言 ...
- 基于SSH框架的考勤管理系统的设计与实现
基于SSH框架的考勤管理系统的设计与实现
- 好的框架需要好的 API 设计 —— API 设计的六个原则
说到框架设计,打心底都会觉得很大很宽泛,而 API 设计是框架设计中的重要组成部分.相比于有很多大佬都认可的面向对象的六大原则.23 种常见的设计模式来说,API 设计确实缺少行业公认的原则或者说设计 ...
- 基于layui的框架模版,采用模块化设计,接口分离,组件化思想
代码地址如下:http://www.demodashi.com/demo/13362.html 1. 准备工作 编辑器vscode,需要安装liveServer插件在前端开启静态服务器 或者使用hbu ...
- js框架漫谈
现在实际项目中可供选择的javascript框架很多,热门的有jquery,dojo,mootools,ext等.这些框架按照不同的标准有不同的分类方法,比如按照扩展方式便可分为prototype式的 ...
- Android酷炫实用的开源框架(UI框架)
Android酷炫实用的开源框架(UI框架) 前言 忙碌的工作终于可以停息一段时间了,最近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮 ...
- Android酷炫实用的开源框架(UI框架) 转
Android酷炫实用的开源框架(UI框架) 前言 忙碌的工作终于可以停息一段时间了,最近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮 ...
随机推荐
- 【C++实现】HeadFirst策略模式设计模式
策略模式定义了算法家族.分别封装起来.让它们之间能够相互替换,此模式让算法的变化独立于使用算法的客户. Head First设计模式中介绍策略模式时以Duck类作为样例.当中用flyBehavior和 ...
- CSharp设计模式读书笔记(10):装饰模式(学习难度:★★★☆☆,使用频率:★★★☆☆)
装饰模式(Decorator Pattern): 动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活. 模式角色与结构: 示例代码: using System; u ...
- 项目开发经常使用PHP功能
日期操作 为了便于存储.比较和交付.我们通常使用strtotime()功能转换的日期UNIX时间戳.有仅用于在显示给用户时date()成经常使用的时间格式. strtotime() 函数将不论什么英 ...
- 深入struts2.0(五)--Dispatcher类
1.1.1 serviceAction方法 在上个Filter方法中我们会看到例如以下代码: this.execute.executeAction(request, response, m ...
- springmvc实现long-pulling技术
背景介绍: 项目中有一个通讯模块,本来是用websocket全双工技术实现的,但IE10下面不支持websocket,而国内的360.2345浏 览器封装的所有是IE10下面的内核,考虑到站点在国内的 ...
- how tomcat works 读书笔记九 Session管理
在看本文之前,请先查阅相关Session与Cookie的资料. 这篇资料不错 http://blog.csdn.net/fangaoxin/article/details/6952954 Catali ...
- Windows系统服务的编写。
实验资源下载地址:点击打开链接 只是不知道能不能从服务向桌面进程传递消息,,就像两个桌面进程之间用Sendmessage似的..希望有知道的大神可以指点一下..不胜感激.. 因为微软在Vista之后, ...
- Java利用jcifs集成AD域用户认证
近期一段时间发现AD这东西老火了,尤其是涉及到安全这一方面的,所以AD域用户认证成了如今网络安全方面的产品必备!这里就简单的分享一下,Java通过jcifs集成AD域用户实现认证,以实现网络安全! 我 ...
- inux平台的C与C++
课堂里学不到的C与C++那些事(一) 首先,声明一下这是一个系列的文章.至于整个系列有多少篇,笔者也不知道,不知道有多少篇,也不知道多久会更新一篇.反正只有一个原则,写出来的文 章能见得人才会公布出来 ...
- SQL Server中存储过程比直接运行SQL语句慢的原因
原文:SQL Server中存储过程比直接运行SQL语句慢的原因 在很多的资料中都描述说SQLSERVER的存储过程较普通的SQL语句有以下优点: 1. 存储过程只在创造时进行编译即可,以 ...