为了更好地让初学者轻松入门,这里仍然采用趣味性的方式聊一些常用技术点,致力于.NET新手们的快速提高!知识都是普通的,关键是学习的思路。技术源于生活,技术原来可以这样学。抛砖引玉而已。   层次结构在现实社会里随处可见。记得有个笑话讲有个村长得意地向他老婆吹牛:“全中国只有四个人比我官大,乡长、县长、省长和国务院总理”。这个笑话也体现了真实社会中分层的现象。社会人群会分层,公司人员结构也会分层,楼房是分层的,甚至做包子的笼屉都是分层的。虽然分层的目的各有不同,但都是为解决某一问题而产生的。所以,分层架构其实是为了解决某一问题而产生的一种解决方案。14.1.1  常用的三层架构设计   软件系统最常用的一般会讲到三层架构,其实就是将整个业务应用划分为表示层、业务逻辑层、数据访问层等,有的还要细一些,通过分解业务细节,将不同的功能代码分散开来,更利于系统的设计和开发,同时为可能的变更提供了更小的单元,十分有利于系统的维护和扩展。   常见的三层架构基本包括如下几个部分,如图 14-1 所示。
[align=center]
图 14- 1   常见的三层架构[/align]l  数据访问层 DAL :用于实现与数据库的交互和访问,从数据库获取数据或保存数据到数据库的部分。l  业务逻辑层 BLL :业务逻辑层承上启下,用于对上下交互的数据进行逻辑处理,实现业务目标。l  表示层 Web :主要实现和用户的交互,接收用户请求或返回用户请求的数据结果的展现,而具体的数据处理则交给业务逻辑层和数据访问层去处理。 日常开发的很多情况下为了复用一些共同的东西,会把一些各层都用的东西抽象出来。如我们将数据对象实体和方法分离,以便在多个层中传递, 例如称为 Model 。一些共性的通用辅助类和工具方法,如数据校验、缓存处理、加解密处理等,为了让各个层之间复用,也单独分离出来,作为独立的模块使用,例如称为 Common 。 此时,三层架构会演变为如图 14-2 所示的情况。
[align=center]
图 14- 2   三层架构演变结果
[/align]
l  业务实体 Model : 用于封装实体类数据结构,一般用于映射数据库的数据表或视图,用以描述业务中客观存在的对象。 Model 分离出来是为了更好地解耦,为了更好地发挥分层的作用,更好地进行复用和扩展,增强灵活性。l  通用类库 Common :通用的辅助工具类。 在第 5.2 节中我们讲过可以将对数据库的共性操作抽象封装成数据操作类(例如 DbHelperSQL ),以便更好地复用和使代码简洁。数据层底层使用通用数据库操作类来访问数据库,最后完整的三层架构如图 14-3 所示。[align=center] 图 14- 3   最后完整的三层架构[/align] 数据库访问类 是对 ADO.NET 的封装,封装了一些常用的重复的数据库操作。如微软的企业库 SQLHelper.cs ,动软的 DBUtility/DbHelperSQL 等,为 DAL 提供访问数据库的辅助工具类。 通过以上分析,我们知道如今常用的三层架构是个什么样子,同时,我们也知道了三层架构在使用过程中的一些演化过程。那么,为什么要这样分层,每层结构到底又起什么作用呢?我们继续往下看。
14.1.2  趣味理解:三层架构与养猪  看新闻报道今年猪肉价格一路高涨,据说有人养猪都发财致富奔小康了,程序员都说写代码没前途了,还不如去养猪,不过,可别认为养猪没有技术含量,比写代码容易,其实养猪也大有学问。为了更好地理解三层架构,就拿养猪来做个例子吧。俗话说:“没吃过猪肉,还没见过猪跑啊!”。 图 14-4 是三层架构化的养猪产业流水线趣味对此图。[align=center] 图 14-4   三层结构与养猪[/align]  对比图 14-3 与图 14- 4 ,我们可以看出:l  数据库好比猪圈 ,所有的猪有序地按区域或编号,存放在不同的猪栏里。l  DAL 好比是屠宰场 ,把猪从猪圈取出来进行(处理)屠杀,按要求取出相应的部位(字段),或者进行归类整理(统计),形成整箱的猪肉(数据集),传送给食品加工厂( BLL )。本来这里都是同一伙人既管抓猪,又管杀猪的,后来觉得效率太低了,就让一部分人出来专管抓猪了( DBUtility ),根据要求来抓取指定的猪。l  BLL 好比食品加工厂 ,将猪肉深加工成各种可以食用的食品(业务处理)。l  Web 好比商场 ,将食品包装成漂亮的可以销售的产品,展现给顾客( UI 表现层)。l  猪肉好比 Model ,无论是哪个厂(层),各个环节传递的本质都是猪肉,猪肉贯穿整个过程。l  通用类库 Common 相当于工人使用的各种工具,为各个厂(层)提供诸如杀猪刀、绳子、剪刀、包装箱、工具车等共用的常用工具(类)。其实,每个部门本来是可以自己制作自己的工具的,但是那样会使效率比较低,而且也不专业,并且很多工作都会是重复的。因此,就专门有人开了这样的工厂来制作这些工具,提供给各个工厂,有了这样的分工,工厂就可以专心做自己的事情了。 当然,这里只是形象的比喻,目的是为了让大家更好地理解,实际的情况在细节上会有所不同。这个例子也只是说明了从猪圈到商场的单向过程,而实际三层开发中的数据交互是双向的,可取可存。不过,据说有一种机器,把猪从这头赶进去,另一头就噗噗噜噜地出火腿肠了。如果火腿肠卖不了了,从那头再放进去,这头猪又原原本本出来了,科幻的机器吧,没想到也可以和三层结构联系上。以上只是笑谈,不过也使三层架构的基本概念更容易理解了。  上面谈了那么多,有人会问,我直接从数据库取出内容直接操作不可以吗?为什么要这么麻烦地用三层架构呢?三层架构到底有什么好处呢? 不分层,当然可以,就好比整个过程不分屠宰场、加工场之类的,都在同一个场所(工厂)完成所有的活(屠杀、加工、销售)。但为什么要加工厂和商场呢?因为当规模比较大的时候,管理起来就会变得非常复杂,这样的养殖方式已经无法满足规模化的需要了。并且,从社会的发展来看,社会分工是人类进步的表现 。社会分工的优势就是让适合的人做自己擅长的事情,使平均社会劳动时间大大缩短,生产效率显著提高。能够提供优质高效劳动产品的人才能在市场竞争中获得高利润和高价值。人尽其才,物尽其用最深刻的含义就是由社会分工得出的。软件开发也一样,做小项目的时候,分不分层确实看不出什么差别,并且显得更麻烦啰嗦了。但当项目变大和变复杂时,分层就显示出它的优势来了。所以分不分层要根据项目的实际情况而定,不能一概而论。 
    原文:http://blog.csdn.net/litp/archive/2009/06/30/4311321.aspx

解决方案 »

  1.   

    litp 能讲一下 .net 3.5下用linq开发三层的经验吗?
      

  2.   

    Model和Common我不会用啊!一直搞不懂!
      

  3.   

    bingg 的杀猪方式好像是作坊式的,不应该算三层架构了,因为没有表示层(商场),加工完就吃了,哈哈,玩笑
      

  4.   

    不错,有没有好理解的例子啊 ,发一个,学习学习。一例胜千言。
    Email:[email protected]
      

  5.   

    我还是有点模糊,讲出我的困惑。
    一直以来,我都认为通用数据访问类就是数据访问层
    理由:
    就拿调用通用数据访问类的 GetDataSet函数为例
    调用存储过程-->调用通用数据访问类的 GetDataSet函数-->返回数据给dataset数据集供我们访问
    你能不能就此例说明一下,各个阶段怎么对应抓猪,杀猪,整理猪,他们这些事件不都是通用数据访问类做啦吗,这样理解,通用数据访问类不就是数据访问层吗,可能我的理解有点狭隘?
      

  6.   


    谢谢你的支持。
    1.其实每章前的设计,只是作为学技术中间的一个趣味休闲的小插曲。就像吃完饭的小甜饼或水果沙拉,虽然到处都有,但放在这个时候提供会有一些不同的感受。网上虽然很多也并不是每个人都看过。所以,提供给大家休息会心一笑之余,略有所悟当然更好。
    2.忘记说明用户名密码,确实是说明文本的疏漏。不过如果以前用过动软的用户或下载过动软示例项目的基本都知道这个数据的密码就是admin,1。不过还是在这里感谢你的提醒。我们在修订版里一定完善。
      

  7.   


    形象的来说,数据层的功能是获取数据(这里面是有逻辑的),而通用数据访问类只是个工具类,根据数据层的sql要求查询数据,他自身没有逻辑,只是个工具,分离出通话数据访问类只是方便数据访问层获取数据。
    也就是说没有通用数据访问类,数据层同样可以获取数据。
    就像屠宰厂的人同样可以抓猪一样,只不过是麻烦点。如果有单独一帮人专管抓猪,分工会更好的提高效率。至于存储过程的例子则稍微有所不同,如果非要较真用抓猪去理解的话,可以这里理解:
    数据访问层------屠宰场
    通用数据访问类---专管抓猪的人(自己没有思想的,只是执行屠宰场的命令而已)
    DB(存储过程)----- 猪圈(里面还有一个管猪的人)如果有存储过程,数据访问类调用存储过程返回数据,其实并没有具体接触数据,返回的数据有存储过程决定的,则可以理解是在猪圈里面还有一个管猪的人。
    而这时候,数据层传给“专管抓猪的人(通用数据访问类)”,并不是“抓什么样的猪的命令(SQL)”,而是说“去找某人要猪就可以了,他已经准备好了(直接调用某个存储过程,存储过程已经查好数据了)”,存储过程已经按逻辑查询数据了,数据层其实也不知道返回的数据是什么,而由存储过程决定的。
     不知道这样比喻你是否能理解了?
      

  8.   

    理解了谢谢老师指导!
    还有个问题问老师,我是不是可以这样简单理解:
    Web层对应到 aspx页,BLL 对应到整个aspx.cs,DAL而对应到aspx.cs里面需要进行数据处理的代码段(这段代码中调用通用数据访问类)呢?
      

  9.   

    说得很贴切,好理解。
    一直做的是WEB页面显示数据,BLL处理各种各样的SQL业务语句,DAL共用处理和获得数据
    LZ说的Model和Common没用到过,对此有些困惑,能否讲解下呢
    谢谢