三层架构之泛型应用

开发 前端 架构
一说到三层架构,我想大家都了解,这里就简单说下,三层架构一般包含:UI层、DAL层、BLL层,其中每层由Model实体类来传递,所以Model也算是三层架构之一了,例外为了数据库的迁移或者更OO点,DAL层就衍生出了IDAL接口。Model就是简单的对应数据库里面的类,DAL层就是主要操作数据库的方法了,BLL这个就看业务了。

一说到三层架构,我想大家都了解,这里就简单说下,三层架构一般包含:UI层、DAL层、BLL层,其中每层由Model实体类来传递,所以Model也算是三层架构之一了,例外为了数据库的迁移或者更OO点,DAL层就衍生出了IDAL接口。Model就是简单的对应数据库里面的类,DAL层就是主要操作数据库的方法了,BLL这个就看业务了。而DAL层大部分的方法都是差不多,无非就是几个Insert,Update,Delete,Select。

再来说下泛型,这个是2.0才开始有的,算是2.0中一个非常重要的技术了,关于泛型有什么好处优点就不说了,网上一大堆,其实说了也没有什么用,大家在实践中运用了就知道,我觉得泛型一个最核心的地方就是,泛型封装了类型,把类型的定义延迟到了客户端,泛型又像一个类型的模板,只要你定义了一个泛型类,就相当于定义了N个类,每个类的类型不一样而已。

上面我们说了,三层架构中的DAL层一般包括Insert,Update,Delete,Select这几种了,那么在泛型还没有到来之前,我们的程序员兄弟一般是怎么做的,首先为每个实体定义一个DAL接口,比如有个User这个实体对象,那么就有一个IUserDAL这个接口以及UserDAL这个实现类,如果有N个实体,那么差不多就需要N个接口和实现类了,而这些接口中的Insert,Update,Delete,Select的方法签名都是类似的,唯一的不同就是方法参数和返回值的类型了,我们来看下基本的接口定义

 

  1. public interface IUserDAL  
  2.      {  
  3.         int Insert(User model);  
  4.         int Update(User model);  
  5.         int Delete(int id);  
  6.         User GetModel(int id);  
  7.         DataTable GetList();  
  8.     } 

那么在一个项目中,像这样的接口定义到处可见,大部分是重复的写法,虽然我们有任劳任怨的代码生成工具为我们效劳,但是从设计角度或者站在新技术的角度看,这些代码就显得很不优雅,很不爽了,我想你的感觉也是这样吧,呵呵O(∩_∩)O~。

当泛型来临时,我们终于可以不看到那么多的重复接口的定义了,终于可以喘一口气了,那么泛型又是怎么实现的呢,在实现之前我们回头看下我们没有泛型的IUserDAL的定义,其中Insert,Update方法就一个User参数,类似的其他接口也就一个参数,只是类型不是User了,可能是Order,或者其他的,在来看下GetModel返回值类型是User,GetList也是一样的,只是这里我们用DataTable这个万能的类型来代替了,但是大家都知道DataTable这个类型臃肿又是弱类型的,在UI层调用的时候又不知道这个DataTable里面到底有什么字段,这个就在开发期带来一定的麻烦。

泛型的实现终于上场了,其实很简单,不就是一对尖括号吗,是的,只要在IUserDAL后面加对尖括号,里面用一个字符代替类型就可以了,哦,对了还要加个泛型约束呢,就是一个where,也就是说,这个泛型的类型只能是引用的类型,不能是值类型,难道你的Model是一个值类型??不可能吧,反正我是不信。那么这个泛型接口的定义就是:

  1. public interface IDAL<T> where T : class  
  2.     {  
  3.         int Insert(T model);  
  4.         int Update(T model);  
  5.         int Delete(int id);  
  6.         T GetModel(int id);  
  7.         IList<T> GetList();  
  8.    } 

 

哦,原来那么简单就是加个T把之前的User类型给【换了】就可以啦,我怎么没有想到呢,呜呜,那么在UserDAL这个继承类中就可以明确定义那个泛型的类型了,因为我这个类就是用来实现User这个实体类的(或者说数据库的表吧),这里,UserDAL我们就叫IUserDAL的客户端了。代码如下:

  1. public class UserDAL : IDAL<User> 
  2.     {  
  3.         #region IDAL<User> 成员  
  4.         public int Insert(User model)  
  5.         {  
  6.             //coding  
  7.         }  
  8.         public int Update(User model)  
  9.         {  
  10.             //coding  
  11.         }  
  12.         public int Delete(object id)  
  13.         {  
  14.             //coding  
  15.         }  
  16.         public User GetModel(object id)  
  17.         {  
  18.             //coding  
  19.         }  
  20.         public IList<User> GetList()  
  21.         {  
  22.             //coding  
  23.         }  
  24.         #endregion  
  25.     } 

 

好了,我们解放了DAL和IDAL,那么BLL层可以用泛型吗,当然可以。

我们先来说下,不用泛型的BLL层的实现,这里不考虑BLL的业务的话,那么BLL就是单纯的调用DAL的相关数据库操作方法,也就是那个IUserDAL接口定义的方法了,一般的UserBLL代码如下:

  1. public class UserBLL  
  2.      {  
  3.          private IUserDAL dal = new UserDAL();  
  4.    
  5.          public int Insert(User model)  
  6.          {  
  7.              return dal.Insert(model);  
  8.          }  
  9.    
  10.          public int Update(User model)  
  11.          {  
  12.              return dal.Update(model);  
  13.          }  
  14.          public int Delete(int id)  
  15.          {  
  16.              return dal.Delete(id);  
  17.          }  
  18.          public T GetModel(int id)  
  19.          {  
  20.              return dal.GetModel(id);  
  21.          }  
  22.          public DataTable GetList()  
  23.          {  
  24.              return dal.GetList();  
  25.          }  
  26.      } 

 

我想这个是最简单的BLL代码了,而且大部分小的项目这样就已经够了,因为没有什么业务嘛,但是如果想这样的代码每个BLL都这样谢,一个项目几十个上百个也这样写真的会累死人的,代码工具虽然可以解决,但是当我们看到那么多的重复代码,相似的代码,真的很心痛,难道你不觉得心痛,如果你不觉得或者也不想去改的话或者以后还是那样写重复的代码,用代码工具帮做的话,我想你的code能力也不会怎么提高,废话一下。

那么用泛型的话,我们就可以为所有的BLL定义一个基类,其他类只要继承下,稍微的根据业务的不同增加点业务代码就可以,甚至都可以不用继承了,我们先看代码的实现吧,搞这行代码才是最好说话的,请看下面代码:

  1. public class BaseBLL<T, D> 
  2.         where T : class  
  3.         where D : IDAL<T>,new ()  
  4.     {  
  5.         private D dal = new D();  
  6.         public virtual int Insert(T model)  
  7.         {  
  8.             return dal.Insert(model);  
  9.         }  
  10.         public virtual int Update(T model)  
  11.         {  
  12.             return dal.Update(model);  
  13.         }  
  14.         public virtual int Delete(object id)  
  15.         {  
  16.             return dal.Delete(id);  
  17.         }  
  18.         public virtual T GetModel(object id)  
  19.         {  
  20.             return dal.GetModel(id);  
  21.         }  
  22.         public virtual IList<T> GetList()  
  23.         {  
  24.             return dal.GetList(model);  
  25.         }  
  26.     } 

 

这个也简单把,也就是把实体类换为T,把IDAL接口换为D,并定义D这个类型的约束,也就是说我的这个D一定是一个实现了IDAL这个接口的,而IDAL尖括号里面的T就是BaseBLL里面的T,看到这里,相信大家都应该明白了,如果你想实现UserBLL,就可以继承BaseBLL这个基类,这里为什么把BaseBLL中的方法定义为virtual呢,原因很简单的,因为你的BLL层的其他类不可能就没有业务,不可能就是简单的调用DAL方法吧,其他的BLL类就可以根据业务去override相关的方法了,UserBLL相应代码如下:

  1. public class UserBLL : BaseBLL<User, UserDAL> 
  2.     {  
  3.          
  4.     } 

 

如果UserBLL没有任何业务的话,那就不要继承了,在UI直接用BaseBLL这个泛型类就可以,调用也很简单

BaseBLL<User> dal=new BaseBLL<User>();这样就可以了。

之所以写这篇随笔,是因为08年那时,我刚刚毕业投入工作后第一次看到让我崇拜的代码设计,好像那个时候泛型也刚开始盛行吧。

最后,感谢大家的阅读,希望大家多多支持我的博客,我是最近一个月才开始写博客的,后面会有更精彩的内容等着你来阅读。

作者:风雨彩虹

出处:http://www.cnblogs.com/liubiaocai/

【编辑推荐】

  1. 浅析淘宝数据魔方技术架构
  2. 浅析.NET设计架构十条箴言
  3. 揭秘Google+技术架构
  4. 揭秘新版SkyDrive架构的幕后
  5. 97条架构师须知
责任编辑:陈贻新 来源: 给力的程序员
相关推荐

2011-04-19 13:53:41

三层架构

2012-02-03 09:44:33

.NET

2012-02-07 10:40:13

MVCJava

2013-01-09 11:00:20

架构开发三层架构.NET架构

2009-08-26 18:20:42

三层架构

2009-07-28 17:25:14

ASP.NET三层结构

2009-07-28 15:08:50

MVC三层架构实例

2009-04-30 15:56:50

三层架构MVCMVP

2015-07-02 10:57:11

General框架架构开发

2018-10-31 14:32:53

数据中心网络架构

2018-03-08 15:30:31

超融合架构传统三层架构

2023-09-13 09:00:00

2009-05-06 09:40:04

LINQWEB开发构架

2010-01-08 10:08:06

三层交换技术

2010-02-22 13:41:49

三层交换机

2010-02-04 16:53:36

三层交换技术

2017-06-12 13:18:51

数据报表计算

2012-08-02 11:05:04

系统建模架构

2014-02-12 10:07:07

三层交换原理

2011-05-12 14:24:14

三层架构
点赞
收藏

51CTO技术栈公众号