三层架构搭建

引言:本文不是从理论的角度来探讨三层架构,而是用一个示例来介绍如何建设一个三层架构的项目,并说明项目中各个文件所处的层次与作用。写本文的目的,不是为了说明自己的这个方法有多对,别人的肯定不对,而是希望给那些初学三层架构却不知从何入手的朋友提供一点帮助。因为网上的文章,大多是注重理论的介绍,而忽略了具体的实践应用,或者有示例但讲得不透彻。导致看了之后,理论上又学习了一遍,但还是不知道代码怎么写。所以想从这个方面入手写一下,让从来没做过三层架构的初学者也能照猫画虎,写出代码来。文章表述的是笔者个人对三层架构的认识,肯定有许多不足的地方,欢迎大家指正,小弟也会根据反馈来修改这篇文章。文中的代码是伪代码,仅用来阐明思路。
  正文:
  一提三层架构,大家都知道是表现层(UI),业务逻辑层(BLL)和数据访问层(DAL),而且每层如何细分也都有很多的方法。但具体代码怎么写,到底那些文件算在哪一层,却是模模糊糊的。下面用一个简单的例子来带领大家实战三层架构的项目,这个例子只有一个功能,就是用户的简单管理。
  首先建立一个空白解决方案,添加如下项目及文件
  1、添加ASP.NET Web Application项目,命名为UI,新建Web Form类型文件User.aspx(含User.aspx.cs)
  2、添加ClassLibrary项目,命名为BLL,新建Class类型文件UserBLL.cs
  3、添加ClassLibrary项目,命名为DAL,新建Class类型文件UserDAL.cs。添加SQLHelper引用。(这个是微软的数据访问类,也可以不用,直接编写所有的数据访问代码。我一般用自己写的数据访问类DataAccessHelper )。
  4、添加ClassLibrary项目,命名为Model,新建Class类型文件UserModel.cs
  5、添加ClassLibrary项目,命名为IDAL,新建Interface类型文件IUserDAL.cs
  6、添加ClassLibrary项目,命名为ClassFactory
  相信大家已经看出来了,这个和Petshop的示例没什么区别,而且更简单,因为在下也是通过Petshop学习三层架构的。但一些朋友对于这几个项目所处的层次,以及它们之间的关系,可能比较模糊,这里逐个说明一下:
  1、User.aspx和User.aspx.cs
  这两个文件(以及文件所属的项目,下面也是如此,不再重复强调了)都属于表现层部分。User.aspx比较好理解,因为它就是显示页面了。User.aspx.cs有些人觉得不应该算,而是要划到业务逻辑层中去。如果不做分层的话,那么让User.aspx.cs来处理业务逻辑,甚至操作数据库都没什么问题,但是做分层的话,这样就不应该了。在分层结构中,User.aspx.cs仅应该处理与显示有关的内容,其它部分都不应该涉及。
  举例:我们实现用列表方式显示用户的功能,那么提取信息的工作是由BLL来做的,UI(本例中是User.aspx.cs)调用BLL得到UserInfo后,通过代码绑定到User.aspx的数据控件上,就实现了列表的显示。在此过程中User.aspx.cs对UI没有起到什么作用,仅是用来传递数据,而且因为实际编码中大部分情况都是如此的实现,所以使有些人觉得User.aspx.cs不应该算UI,而应该并入BLL负责逻辑处理。继续往下看,这时提出了一个新需求,要求在每个用户的前面加一个图标,生动地表现出用户的性别,而且不满18岁的用儿童图标表示。这个需求的实现,就轮到User.aspx.cs来做了,这种情况下User.aspx.cs才算有了真正的用途。
  2、NewBLL.cs
  添加如下方法:
  public IList<UserInfo> GetUsers():返回所有的用户信息列表
  public UserInfo GetUser(int UserId):返回指定用户的详细信息
  public bool AddUser(UserInfo User):新增用户信息
  public bool ChangeUser(UserInfo User):更新用户信息
  public void RemoveUser(int UserId):移除用户信息
  此文件就属于业务逻辑层了,专门用来处理与业务逻辑有关的操作。可能有很多人觉得这一层唯一的用途,就是把表现层传过来的数据转发给数据层。这种情况确实很多,但这只能说明项目比较简单,或者项目本身与业务的关系结合的不紧密(比如当前比较流行的MIS),所以造成业务层无事可做,只起到了一个转发的作用。但这不代表业务层可有可无,随着项目的增大,或者业务关系比较多,业务层就会体现出它的作用来了。
  此处最可能造成错误的,就是把数据操作代码划在了业务逻辑层,而把数据库作为了数据访问层。
  举例:有些朋友感觉BLL层意义不大,只是将DAL的数据提上来就转发给了UI,而未作任何处理。看一下这个例子
  BLL层
  SelectUser(UserInfo userInfo)根据传入的username或email得到用户详细信息。
  IsExist(UserInfo userInfo)判断指定的username或email是否存在。
  然后DAL也相应提供方法共BLL调用
  SelectUser(UserInfo userInfo)
  IsExist(UserInfo userInfo)
  这样BLL确实只起到了一个传递的作用。
  但如果这样做:
  BLL.IsExist(Userinfo userinfo)
  {
  UerInfo user = DAL.SelectUser(User);
  return (userInfo.Id != null); 
  }
  那么DAL就无需实现IsExist()方法了,BLL中也就有了逻辑处理的代码。
  3、UserModel.cs
  实体类,这个东西,大家可能觉得不好分层。包括我以前在内,是这样理解的:UIßàModelßàBLLßàModelßàDAL,如此则认为Model在各层之间起到了一个数据传输的桥梁作用。不过在这里,我们不是把事情想简单,而是想复杂了。
  Model是什么?它什么也不是!它在三层架构中是可有可无的。它其实就是面向对象编程中最基本的东西:类。一个桌子是一个类,一条新闻也是一个类,int、string、doublie等也是类,它仅仅是一个类而已。
  这样,Model在三层架构中的位置,和int,string等变量的地位就一样了,没有其它的目的,仅用于数据的存储而已,只不过它存储的是复杂的数据。所以如果你的项目中对象都非常简单,那么不用Model而直接传递多个参数也能做成三层架构。
  那为什么还要有Model呢,它的好处是什么呢。下面是思考一个问题时想到的,插在这里:  
  Model在各层参数传递时到底能起到做大的作用?
  在各层间传递参数时,可以这样:
  AddUser(userId,userName,userPassword,…,)
  也可以这样:
  AddUser(userInfo)
  这两种方法那个好呢。一目了然,肯定是第二种要好很多。
  什么时候用普通变量类型(int,string,guid,double)在各层之间传递参数,什么使用Model传递?下面几个方法:
  SelectUser(int UserId)
  SelectUserByName(string username)
  SelectUserByName(string username,string password)
  SelectUserByEmail(string email)
  SelectUserByEmail(string email,string password)
  可以概括为:
  SelectUser(userId)
  SelectUser(user)
  这里用user这个Model对象囊括了username,password,email这三个参数的四种组合模式。UserId其实也可以合并到user中,但项目中其它BLL都实现了带有id参数的接口,所以这里也保留这一项。 
  传入了userInfo,那如何处理呢,这个就需要按照先后的顺序了,有具体代码决定。
  这里按这个顺序处理
  首先看是否同时具有username和password,然后看是否同时具有email和password,然后看是否有username,然后看是否有email。依次处理。
  这样,如果以后增加一个新内容,会员卡(number),则无需更改接口,只要在DAL的代码中增加对number的支持就行,然后前台增加会员卡一项内容的表现与处理即可。 
  4、UserDAL.cs
  public IList<UserInfo> SelectUsers():返回所有的用户信息列表
  public UserInfo SelectUser(int UserId):返回指定用户的相信信息
  public bool InsertUser(UserInfo User):新增用户信息
  public bool UpdateUser(UserInfo User):更新用户信息
  public void DeleteUser(int UserId):移除用户信息
  很多人最闹不清的就是数据访问层,到底那部分才算数据访问层呢?有些认为数据库就是数据访问层,这是对定义没有搞清楚,DAL是数据访问层而不是数据存储层,因此数据库不可能是这一层的。也有的把SQLHelper(或其同类作用的组件)作为数据访问层,它又是一个可有可无的东西,SQLHelper的作用是减少重复性编码,提高编码效率,因此如果我习惯在乎效率或使用一个非数据库的数据源时,可以丢弃SQLHelper,一个可以随意弃置的部分,又怎么能成为三层架构中的一层呢。
  可以这样定义:与数据源操作有关的代码,就应该放在数据访问层中,属于数据访问层
  5、IUserDAL
  数据访问层接口,这又是一个可有可无的东西,因为Petshop中带了它和ClassFactory类工厂,所以有些项目不论需不需要支持多数据源,都把这两个东西做了进来,有的甚至不建ClassFactory而只建了IDAL,然后“IUserDAL iUserDal = new UserDAL();”,不知意义何在。这就完全是画虎不成反类犬了。
  许多人在这里有一个误解,那就是以为存在这样的关系:BLLßàIDALßàDAL,认为IDAL起到了BLL和DAL之间的桥梁作用,BLL是通过IDAL来调用DAL的。但实际是即使你如此编码:“IUserDAL iUserDal = ClassFacotry.CreateUserDAL();”,那么在执行“iUserDal.SelectUsers()”时,其实还是执行的UserDAL实例,而不是IUserDAL实例,所以IDAL在三层中的位置是与DAL平级的关系。
  通过上面的介绍,基本上将三层架构的层次结构说明了。其实,本人有一个判断三层架构是否标准的方法,那就是将三层中的任意一层完全替换,都不会对其它两层造成影响,这样的构造基本就符合三层标准了(虽然实现起来比较难^_^)。例如如果将项目从B/S改为C/S(或相反),那么除了UI以外,BLL与DAL都不用改动;或者将SQLServer改为Oracle,只需替换SQLServerDAL到OracleDAL,无需其它操作等等。本来想在文中加入一些具体的代码的,但感觉不是很必要,如果大家觉得需要的话,我再补充吧。
  总结:不要因为某个层对你来说没用,或者实现起来特别简单,就认为它没有必要,或者摒弃它,或者挪作它用。只要进行了分层,不管是几层,每一层都要有明确的目的和功能实现,而不要被实际过程所左右,造成同一类文件位于不同层的情况发生。也不要出现同一层实现了不同的功能的情况发生。

 

所谓的三层架构:
控制层
逻辑层
数据层
当然会有一个模型层
那么就是四层
若是所有的访问数据库都用存储过程
那么就不需要模型层
三层就是为了代码维护和可扩展性好一些

 

做 ASP.NET 快五年了,现在才算基本明白了三层架构,
11 楼所讲滴三层架构是俺两年前滴理解,虽然用 Model 取代了 DataTable,
但是写起来仍感觉代码不流畅!

直到前几个月才悟出来,分层并不重要,OO 才是最重要滴!!!

借 11 楼所讲滴三层架构一用,虽然层分滴很华丽,
但是真正滴对象在哪里?对象滴继承在哪里?对象之间滴组合又在哪里?
也许有人会说现在应用很简单,等应用复杂起来就会有了,是真的么?!
答案当然是,非真!

OO 实现与应用滴简单与否并无直接关系,简单应用照样有对象,只是数量少一些,一两个而已,
而 11 楼所讲滴那种三层架构中,虽然有 Model 和 BLL,但恰恰没有真正滴对象,接下来仔细分析一下:

Model 层,一些只有属性、字段而无方法滴类,基本上都是数据库表直接映射而来滴,
虽然用到了 class 关键字,但它们不是类,只是一些数据表滴变体而已,形象一些也可称为数据傀儡,
只能任人摆布,结论 Model 层是一些残疾类滴集合,没有丝毫 OO 滴思想;

BLL 层,一些静态类或者一些提供静态方法(增删改查)滴类,这些类只有方法而无属性、字段,
同样它们也不是类,只是一些加工器而已,OO 思想更与 BLL 毫无关系!

下面来讲讲俺对三层滴理解,从上至下依次为,表示层、业务实体层、数据访问层!

表示层,用于展示、收集数据,与 业务实体层 交互;
业务实体层,暂时跳过;
数据访问层,访问数据源,填充业务实体!

关键就是业务实体,业务实体 = Model + BLL,属性加方法才是对象,因此将 Model 与 BLL 合并
就得到了真正滴业务实体,为了更好滴适应业务需求,业务实体之间可以相互组合,例如:A 班级下可以有
本班学员列表,即 classA.StudentList;业务实体还可以扩展自己滴成员方法,例如:A 班级下找出所有姓
赵滴同学,即 classA.FindAllByLastName("赵");班级类上还有静态方法,例如:新增 A 班级,
即 Class.Add(classA),删除 A 班级,即 Class.Remove(classA)等等!

业务实体主要定义了与本实体相关的属性和方法,至于多对象之间的复杂交互应添加一个新层——业务外观层,
而业务外观层多是一些静态类,为表示层提供一些功能!

复杂三层就变为:

表示层(WebForm or WinForm ...)
| |
| 业务外观层(随需应变)
| |
业务实体层(三层架构的核心)
|
数据访问层(SqlServer or Excel or XML ...)

至于实现,每个团队滴风格不同、架构不同代码自然不同,而理想滴三层架构应该就是俺上面这张图了!

如果不懂 OO,这张图离实现就有十万八千里,想学 OO Coding 就去看《重构》吧,看完这本书
就能实现理想滴三层架构了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值