一、
前言
最近几个网友在讨论程序设计中的分层设计,反响非常激烈。大家对此非常感兴趣,且仁者见仁,智者见智。不管怎么样,他们的看法代表了他们对程序的理解,是他们实践经验的总结,是宝贵的。今天,这里我们且不评论他们的见解正确与否,这里我只谈谈我对分层的看法.希望能起到抛砖引玉的作用。
二、
三层架构开发简介
a)
什么是三层
首先,谈一下什么是三层架构,所谓的三层开发就是将整个业务应用划分为表示层-业务逻辑层―数据访问层-数据库等,有的还要细一些,明确地将客户端的表示层、业务逻辑访问、和数据访问及数据库访问划分出来,十分有利于系统的开发,维护、部署和扩展。
软件要分层,其实总结一句话,是为了实现“高内聚、低耦合”。采用“分而治之”的思想,把问题划分开来各个解决,易于控制,易于延展,易于分配资源。
图1.三层结构示意图
表示层:负责直接跟用户进行交互,一般也就是指我们的前台,用于数据录入,数据显示等。它不应该做太多的工作。表示嘛,也就意味着只做与外观显示相关的工作。不属于他的工作他不用管也不该管。
业务逻辑层:用于做一些有效性验证的工作。以更好的保证程序运行的健壮性。如数据的有效性判断。不允许为的地方是否输入了空字符串,该输入Email的,格式是否正确等,数据类型的合法性判断,该是整型的地方当然不能接受字符串了,数据库操作是否合法,如字段长度的有效性判断。sql防注入的问题,用户的权限的合法性判断等,通过以上的诸多判断以决定是否将操作继续向后传递。尽量保证程序的正常运行
数据访问层:顾名思义,就是用于专门跟数据库进行交互。对数据的添加,删除,修改,显示等。需要强调的是所有的数据对象只在这一层被引用,如System.Data。SqlClient等,除数据层之外的任何地方都不应该出现这样的应用。
ASP.NET可以使用
.NET平台快速方便的部署三层架构。ASP.NET革命性的变化是在网页中也使用基于事件的处理,可以指定处理的后台代码文件,可以使用C#,VB,J#作为后台代码的语言。.NET中可以方便的实现组件的装配,后台代码通过命名控件可以方便的使用自己定义的组件。显示层放在ASPX页面中,数据库操作和逻辑层用组件来实现,这样就很方便的实现了三层架构。
。
b)
为什么使用三层
那么我们为什么要使用分层开发呢,它有什么独特的优势呢?
.NET开发平台为我们做开发提供了强大的技术支持,使我们的开发变得非常便捷,高效。通过code behind的强大支持,我们可以将页面设计和代码设计有效的分离,代码编写,页面设计同时进行。这比古老的asp那种插入式编写要迅速多了,Html归aspx,代码归aspx.cs,看起来倒也蛮清晰的,也没发现有什么不妥的地方
的确,光从功能实现的基础来说我们已经做得很好了,尤其对于一个简单的应用来说,代码量不是很多的情况下,这种一层结构开发完全够用了,没有必要搞得那么复杂。但是对一个复杂的大型系统来说这样的设计的缺陷就很严重了(下面会具体介绍,分层开发其实也是为大型系统服务的),。在开发过程中我们会不停把代码到处复制,以实现一些相似的功能。同样的代码为什么要写那么多次?不但使程序变得冗长,更不利于维护,一个小小的修改或许会波及很多页面。稍微不留神就会导致异常的产生。使程序不能正常运行。最主要的面向对象的思想没有得到丝毫的体现,打着面向对象的幌子却依然走着面向过程的老路。
意识到这样的问题,我开始将程序中一些公用的处理程序写成公共方法封装在类中,供其它程序调用。象一些功能型的代码集合,数据库操作,如同SqlHelper那样对数据操作进行合理封装,把sql语句,参数列表作为参数,在数据库操作过程中,只要传入相应的参数就可以完成特定的数据操作,这就是我一开始的数据访问层,再不用每次操作数据库时都写那些重复性的数据库操作代码。在新的应用开发中,数据访问层可以直接拿来用。面向对象的三大特性之一的封装性在这里得到了很好的体现。似乎找到了面向对象的感觉,代码量较以前有了很大的减少,而且修改的时候也比较方便。这下应该可以了吧?
试问一下,如果有一天数据库供应商发生了变化,因为数据量的增加,数据库有access变成了sql server?这下麻烦大了,原来的数据访问层失效了,数据操作对象发生了变化,且页面中涉及数据对象的地方也要进行修改,因为原来可能会使用OleDbDataReader对象将数据传递给显示页面,现在都得换成SqlDataReader对象,sql和access支持的数据类型也不一致,在显示数据时进行的数据转换可能也要进行修改。由sql向access的转换所做的修改会更多。还有一种情况,因为某种需要,我们要把Web形式的项目改造成windows应用,这时牵涉的修改有多大呢?如果在你的aspx.cs中放了很多处理代码,或者还有一部分代码存在于aspx中呢windows应用中可没有aspx阿,是不是整个系统需要重新来做了?这都是设计不合理惹的祸。再者,就是分布式的情况,现在的设计也无法做到。也就意味着,以上的设计充其量只能算小打小闹。
不知道我的解释是否让你体会了到了一些一层开发模式下的缺陷了呢?你是否碰到过这样的情况呢?幸运的是,多层开发架构的出现很有效的解决了这样的问题。通过将程序架构进行合理的分层,将极大的提高程序的通用性。
三层中,各个层之间的分工是很明确的,面向对象吗,就像一个公司中的部门一样,每个部门的分工是不一样的,是哪个部门的任务就有哪个部门完成,对应的,各个部门的维护工作也有各自完成且不会影响其它的部门,至少影响不是很大,否则就只能说明分层还不合理。各个层之间通过有效的协作来完成系统的高效运行。表示层就是用来做接受/显示数据的工作,它要通过与其它层的协作来完成用户的请求,在这一层不该放太多的代码。逻辑层就是用来做数据有效性判断的,前面已经说过了,数据层就是用来完成底层数据交互的。表示层就不该去实现逻辑层的功能,当然我们会在客户端对用户的输入做一些判断,但服务器端,验证还要做。用户完全可以绕过客户端验证不是吗?现在我们在看上面说的问题,数据库发生了改变,我们只需要修改数据访问层,其它的地方我们都不用去管,这里我倾向于借助自定义数据实体来负责层与层之间的数据交互,我们把数据填充到自定义实体中,使用自定义实体的好处请参考我上面的两篇关于自定义实体的介绍的文章。通过数据访问层来完全封装数据供应商,使数据访问层对其它层完全透明,这样将数据库改变带来的修改完全限定在数据访问层内。我们可以借助一些模式来设计一个通用的数据访问层,这样即使数据库发生改变,我们只要修改一下配置就可以轻松搞定。对于开发平台的改变也变得很容易,不管是windows还是web,变化的只是界面而已,也就是所谓的表示层,它的内核没有变,相当于我们重作一个壳。表示层的代码是很少的,所以修改是很有限的,其它两层也不要修改就可以迅速做到web程序向windows程序的过渡。
你体会到三层的优势了吗?当然多层设计还有很多优秀的地方,我只是介绍了其中的一小部分。下面引入我所理解的三层的概念。
c)
我的三层结构。
那么怎么才能写出一个比较好的三层结构呢?下面说说我在程序设计中采用的做法,当然这里谈的只是我对三层的理解,不一定准确。欢迎拍砖。呵呵
程序设计追求的是代码的通用性,可移植性,可维护性、功能扩展。怎么才能做到这些呢?这需要我们大量的实践经验做支撑。对面向对象思想的深入了解才能做到。个人觉得优秀的多层结构的设计肯定要先精通模式设计,不过遗憾的是对模式设计研究好长一段时间,依然没能领略到它的精髓,研究模式设计真的很过瘾哦。
以上是我在层序设计中所使用的分层示意图。
Web
层:也就是表示层,它负责响应用户的请求,对于这一层越薄越好,一般不应该写太多代码,或者为了页面显示的需要做少量的代码。大量的处理工作都交给其它的层去完成。就好比传递员,只负责接受,并将请求向后传递,具体怎么做它不用管。
Common
层:这里用来封装一些常用的功能性代码,主要用来为其它层服务的。还有存放一些自定义实体类型和自定义实体类型集合。用于各层次之间数据交互的载体。如User,UserCollection,关于自定义实体这里就不展开了,如果系统复杂的话这一层应该比较厚实,包括下面的BLL层也是如此。
BLL
层:就是逻辑层,用来对数据进行有效性验证,牵涉到对敏感数据的操作都需要经过这里做判断,然后才能决定操作是否合法。
Dal
层:数据访问层;封装对数据库的操作。我们可以做一个通用的数据访问层,下次开发的时候,就可以直接拿过来用。很爽的。有一点从这里传进来、传出去的数据都用自定义实体代替,这样就可以实现数据访问层对其它层的完全透明。这里封装所有于数据库相关的代码,包括sql语句,存储过程等。
分层的思路说完了,在多人开发系统的过程中,就可以按层来划分任务,只要设计的时候把接口定义好,开发人员就可以同时开发。而且不会发生冲突,做前台的人根本就不需要知道数据库结构是什么,该怎么去查找,更新,删除数据,他直观调用响应的方法就可以了。数据访问层的人也不需要知道前台发生了什么,定义好与其它层交互的接口,规定好参数就行。各个层都一样,做好自己的工作就可以了,只要能做到对其它层的完全透明。这样就可以将修改限定在一个比较小的范围内。
但各个层具体的代码该怎么组织,我想这就要看个人的造诣了,要开发出高性能,可扩展的代码就需要结合模式设计的思想,通过代码结构的科学、合理的设计方能在日后的维护过程中游刃有余。
三、
总结
1) 从开发角度和应用角度来看,三层架构比双层或单层结构都有更大的优势。三层结构适合群体开发,每人可以有不同的分工,协同工作使效率倍增。开发双层或单层应用时,每个开发人员都应对系统有较深的理解,能力要求很高,开发三层应用时,则可以结合多方面的人才,只需少数人对系统全面了解,从一定程度工降低了开发的难度
2) 三层架构可以更好的支持分布式计算环境。逻辑层的应用程序可以有多个机器上运行,充分利用网络的计算功能。分布式计算的潜力巨大,远比升级CPU有效。美国人曾利用分式计算解密,几个月就破解了据称永远都破不了的密码
3) 也是三层架构的最大优点是它的安全性。用户端只能通过逻辑层来访问数据层,减少了入口点,把很多危险的系统功能都屏蔽了