【Yom框架】漫谈个人框架的设计之【是IRepository还是IRepository<T>】?

前言                                                                                                                 

对于仓储Repository的设计,其实很多人都很纠结,因为从广义来说,Repository有两种类型:

IRepositoryIRepository<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接口

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

 
 

框架的设计之IRepository还是IRepository<T>的更多相关文章

  1. 【Yom框架】漫谈个人框架的设计之一:是IRepository还是IRepository<T>?

    前言                                                                                                   ...

  2. 【Yom框架】漫谈个人框架的设计之二:新的IRepository接口+搜索和排序解耦(+基于Castle实现)

    经过了上篇IRepository和IRepository<T>的讨论[文章地址为:http://www.cnblogs.com/yomho/p/3296759.html] 我选择了IRep ...

  3. 【Yom框架】漫谈个人框架的设计之三:业务接口+UI层的设计(基于Castle实现的Repository)

    Repository层设计的文章见:[http://www.cnblogs.com/yomho/p/3297042.html]   一.概要设计 上面Reposity 应该为 Repository 特 ...

  4. [连载]《C#通讯(串口和网络)框架的设计与实现》- 11.调试器的设计

    目       录 第十一章     调试器设计... 2 11.1         调试接口... 2 11.2         界面方式调试... 3 11.3         命令行方式调试.. ...

  5. [连载]《C#通讯(串口和网络)框架的设计与实现》-1.通讯框架介绍

    [连载]<C#通讯(串口和网络)框架的设计与实现>- 0.前言 目       录 第一章           通讯框架介绍... 2 1.1           通讯的本质... 2 1 ...

  6. [连载]《C#通讯(串口和网络)框架的设计与实现》-2.框架的总体设计

    目       录 C#通讯(串口和网络)框架的设计与实现... 1 (SuperIO)- 框架的总体设计... 1 第二章           框架总体的设计... 2 2.1           ...

  7. Mybatis原理分析之二:框架整体设计

    1.引言 本文主要讲解Mybatis的整体程序设计,理清楚框架的主要脉络.后面文章我们再详细讲解各个组件. 2.整体设计 2.1 总体流程 (1)加载配置并初始化       触发条件:加载配置文件 ...

  8. Java日志系统框架的设计与实现

    推荐一篇好的文章介绍java日志系统框架的设计的文章:http://soft.chinabyte.com/database/438/11321938.shtml 文章内容总结: 日志系统对跟踪调试.程 ...

  9. activiti5.13 框架 数据库设计说明书

    转载自:http://www.cnblogs.com/llzgzljl/p/3356108.html activiti5.13 框架 数据库设计说明书 1.结构设计 1.1.    逻辑结构设计 Ac ...

随机推荐

  1. 欧拉计划&#183;Q8

    题目8:找出这个1000位数字中连续13个数字乘积的最大值. 找出下面这个1000位的整数中连续13个数字的最大乘积. 7316717653133062491922511967442657474235 ...

  2. my97 日期控件

    官网:http://www.my97.net/   好多广告啊! 文档地址: http://www.mysuc.com/test/My97DatePicker/

  3. KnockOut绑定

    KnockOut绑定之Click绑定 Click绑定对DOM元素添加一个函数,当DOM元素被点击的时候调用.在button,input 或者a标签中常用,但其实他适用于任何可见的DOM元素. exam ...

  4. MVC4 学习笔记01

    1 . ASP.NET MVC 中 ActionResult 和 ViewResult 在使用上的区别是什么?要注意什么吗? ActionResult 是一个抽象(abstract)类,ViewRes ...

  5. 利用svn自动同步更新到网站服务器 -- 网摘

    首先在服务器上安装VisualSVN Server ,根据提示选好安装的路径,一路确定.安装好后运行VisualSVN Server ,在Repositories上点击右键,选择create New ...

  6. [Openstack] Expecting an auth URL via either --os-auth-url or env[OS_AUTH_URL]

    直接使用devstack在ubuntu14.04单个节点的建筑openstack 使用keystone查询租户和用户始终报告时,这个错误! 主要看下这些配置是否正确.我们将能够解决这个问题 opens ...

  7. 湘潭oj1203/邀请赛A称号 数论+java睑板

    乞讨 n%1+n%2+n%3+n%4+.........n%n=,n<=10^12次要. 一味的找规律之初.没有发现.后来,前辈执教后,人才平淡,所以,现在唯一明确的. 首先在地图上: 对于该题 ...

  8. UIAutomator源码分析之启动和运行

    通过上一篇<Android4.3引入的UiAutomation新框架官方简介>我们可以看到UiAutomator其实就是使用了UiAutomation这个新框架,通过调用Accessibi ...

  9. php错误及异常捕捉

    原文:php错误及异常捕捉 在实际开发中,错误及异常捕捉仅仅靠try{}catch()是远远不够的. 所以引用以下几中函数. a)   set_error_handler 一般用于捕捉  E_NOTI ...

  10. POJ 1028 Web Navigation 题解

    考查代码能力的题目.也能够说是算法水题,呵呵. 推荐新手练习代码能力. 要添加难度就使用纯C实现一下stack,那么就有点难度了,能够使用数组模拟环形栈.做多了,我就直接使用STL了. #includ ...