近日看到了一篇关于反三层的文章,手也痒痒了,就牺牲些时间,拿出来把这个老得掉牙的话题拿出重谈。
1. 什么是三层
很多人爱把三层架构和MVC混为一谈,但是我们可以从最简单的角度去考虑他们的不同:
在设计模式中一般都会有这样一章,MVC设计模式,而从没见过哪本书中有写过三层架构设计模式。
回归三层,三层一般来讲分为两类:
A. 物理上的三层架构
B. 逻辑上的三层架构
现在就逐个谈起,来看下究竟三层是否要走开。
2. 逻辑三层架构
逻辑三层架构从概念上看很容易,用户界面层,业务逻辑层,数据访问层。每一层都有自己所专有的职责。
三层架构是一切企业级架构的核心,直至Petshop中的七层,或者是一般企业中的五层都是以三层做为一个中心,在这里,我们可以说N=3。
用户界面层专职显示工作,与用户直接打交道。
业务逻辑层用于做一些复杂的业务处理。
数据访问层用于与数据库做一个交互,做常规的增删改查的操作。
这些很简单,点到为止。
3. 物理三层架构
物理三层架构是以逻辑的三层架构为基础的。如果没有了逻辑的三层,就根本谈不上物理三层架构的部署。
什么是物理三层架构?
从简单了说就是每一层都分别做成一个组件,如业务逻辑组件,业务实体组件,数据访问组件等。
再到麻烦了一些就是构建分布式系统,例如将业务逻辑层与数据访问分别部署再不同的服务器上。
4. 再论存储过程
存储过程作为一个SQLAS,与每门语言一样,也有着自己的优点和缺点。
来与数据库打交道无非三个方法:
A. 在程序逻辑中书写SQL语句,其中包含SQL字符串拼接最为常见
B. 在数据访问层使用ORM框架,在.NET项目中以LINQ TO SQL和NHibernate为主。(其实两者在实际项目中都不常用)
C. 使用存储过程
我们来分析一下他们之间的优缺点:
在程序逻辑中写SQL语句是很难处理复杂业务逻辑的,困难的引号匹配,复杂的字符串拼接过程,以及字符串拼接过程中的效率损失是我们不得不考虑的。
ORM框架是一个好办法,这个我不报什么怀疑意见,但是LINQ TO SQL略显蹩脚的语法,让常规程序员在C#和LINQ之间来回转换不是件容易事。NHibernate就不说了,这个在中国大多数公司来说还算是个非主流框架,而且与VS的集成不是很令人满意。
于是,处理复杂逻辑,如复杂的事务处理时,存储过程几乎成了唯一的方法。
但是,存储过程一样有着他的致命缺点,就是他的移植性很差,
A. 当我们的项目更换数据库时,我们就要把存储过程完整地去拷贝到另外一个数据库,然后考虑他们的兼容问题。
B. 当我们修改数据层访问代码时,我们需要动的不再是应用程序服务器的代码,而是数据库端的代码,这是稍显痛苦的地方 。
5. 三层的优点
现在有人去质疑三层,让三层走开,问题不在于三层。而在于他错用了三层。好刀要用在刃上,否则,恐怕只会弄巧成拙。
那么下面就说三层的优点究竟在哪?
A. 正如上面而言,逻辑上的三层是物理上三层的前提条件。
B. 三层可以让团队开发中,每个成员有着自己的关注点,而且利于小组成员的分工。
C. 重用数据访问层和业务逻辑层
D. 多语言协作(如数据访问层用vb,业务逻辑层用C#,情况很少见)
E. 一定程序上的易维护,但我个人认为这点体现的不明显,就像那位兄弟讲的那样,如果修改一个字段,需要在三层都进行修改。
6. 三层不三层
究竟是三层还是不三层,这一直是困扰很多人的问题。
正如每一种设计模式一样,这些都是一把双刃剑,用得好了会让你很方便,但是用错了却是适得其反。
是否三层,要纵观整个项目,然后去提前挖掘他的潜在变化点,然后再去想,如果这个项目用了三层对你有什么好处。
如果你想不到,那么就不要去三层。
常用三层的情况如下:
A. 产品型公司需要向上屏蔽底层细节,因此需要封装好很多访问以及业务逻辑,这个时候必须三层。
B. 项目很大,需要多成员合作,让一个成员既关注顶层的业务逻辑,又要关注页面美观,还要去注意数据访问的效率,这是不现实的。
C. 项目巨大,需要应用程序逻辑分布式。
7. 三层之扩展
在我所有的文章中,都在强调思想的重要性,我不喜欢被前人去限制住自己的思路,不喜欢轻易相信书上的观点,除非被我证实过。本篇也是一样。
究竟是三层,我觉得三层本就是一个思想,没必要说这样就是三层,那样就不是三层,这就把知识学的太死了。
还记得国外哪位大师给AJAX下的定义:只要能够提高用户体验的技术,我们就将之统称为AJAX。
其实,我个人认为三层也是一样:能够让我们的项目适应变化,可重用,方便程序员的架构方法,我们就可以称之为三层。
8. 扩展三层分类
A. 简化版三层:
当业务逻辑简单时,就把业务逻辑层简化,于是就形成了这样的结构:
.aspx为用户界面层 .aspx.cs为业务逻辑层 .cs单独搭建数据访问层
B. 一些变化
通常的公司都会有自己数据访问类,就像Petshop中的SqlHelper。我们也可以把这单独叫成一层,不过这都是概念问题了。
C. 分出业务逻辑和业务实体
对于很多项目来说,业务逻辑处理都是相对复杂的,说个简单的,比如在登陆界面,当传出密码到存入数据库,就需要一个加密的过程,我们就可以把这个过程封装到业务逻辑层内。另外,比如一些复杂的流程处理,我们同样可以在业务逻辑层去。
业务实体就不说了,这个很常见。
D. 无业务实体
在很多办公OA的项目中,数据往往是无实体的,因为用户可以根据自己的选择去动态地构建数据库表字段,因此这个时候,业务实体就没有存在的必要了。
E. 极端简化
在很多小项目中,业务流程简单,数据处理容易,更没有一些复杂的操作,没有团队合作,那么我们就没有必要去分层。这个时候的分层只会让我们的编码量以及维护量更大。那么这种情况算什么?
我之前提过这个概念,只要能够让我们的项目适应变化,可重用,方便程序员的开发,我就把他叫做三层,那么这么来说,这种最简单的方式其实我们也能把他勉强叫成是“三层”吧。
9 . 总结
三层不三层,三层要怎么三层,这本来就是一个很难去抉择的问题。
所以,我还是那个观点,适应变化的架构方式就是最好的方式。