NET平台上的分层架构(不少朋友称其为“三层架构”),彷佛是一个长盛不衰的话题。常常看到许多朋友对其进行分析、探讨、辩论甚至是抨击。笔者在仔细阅读了大量这方面文章后,认为许多朋友在分层架构的理解上存在两个比较大的偏颇:
1.没有从本质角度去理解分层的内涵,而只是了解其表象。
2.对分层架构的理解过于狭隘,只是少数概念,而又不够深刻。
许多朋友言“分层”则必称“DAL”、“BLL”、“表示层”等概念,却不知“DAL”的内部还有“Data Source 架构模式”、“Object-Relational Behavioral 模式”、“Object-Relational Structural 模式”等方面,而其中每一个方面下下又有诸多具体模式,如“Data Source 架构模式”又有“Table Data Gateway”、“Row Data Gateway”、“Acitive Record”等等。再说“BLL”,你们都知道“BLL”是“业务逻辑层”,但是什么是“业务逻辑”?“BLL”又能够构建为“Transaction Script”、“Domain Model”、“Table Module”三种模式,各是什么意思?另外,分层也不只只有“数据访问层”+“业务逻辑层”+“表示层”这一种分法,诸如“服务层”、“持久化层”、“应用控制层”的概念朋友们是否真的熟悉呢。
形成这种现象,我想很大一部分缘由是由于大多数.NET平台的开发者(包括我在内)理解分层架构是从Microsoft的PetShop开始的。由于PetShop是官方的Demo,因此被众多.NET开发者奉为圣经,甚至成了.NET平台上分层架构的标准方案。我就曾看到许多朋友在个人博客中留下“分层架构仍是PetShop最经典”、“想学分层仍是看PetShop吧”、“你这是跟PetShop学得吧”这样的留言。朋友们太崇敬PetShop了,却忽略了一个事实:它仅仅是一个Demo。退一步说,即便它是一个实际应用的项目,这样经过一个具体项目去定义一个抽象概念的方式也是不科学的。
举个例子,一我的不知道“牛”是什么东西,因而请教一位奶牛场管理员,管理员迁出一头奶牛,告诉他:“这就是牛”。今后之后,若是有人问他“牛”是什么,他就会告诉别人“牛”是一种体型庞大,行动笨拙,性格温顺,身上有黑白斑块图案,还有一个好大的咪咪,能够挤奶供人喝。有一天,他据说西班牙有斗牛这项运动,他大惊道:“这怎么能够!牛那么温顺,怎么能用来斗呢!并且牛是用来挤奶喝的啊!”
故事中这我的犯了一个什么错误呢?他把“具体的一头奶牛”和“牛”这个抽象概念给划等号了。他认为牛就是“体型庞大,行动笨拙,性格温顺,身上有黑白斑块图案,还有一个好大的咪咪,能够挤奶供人喝”。却不知这世界上还有黄牛、水牛、牦牛、斗牛、肉牛等各类牛。他没能作到“透过想象看本质”从而造成抽象概念,而犯了“一叶障目”的错误。
其实,许多朋友之因此对分层架构理解片面或偏颇,是由于与故事中这我的犯了相同的错误。
当初,咱们不知道何为“分层架构”,因而微软给了咱们一个PetShop,说:“看!这就是.NET平台下分层架构的产品。”因而咱们“恍然大悟”:“噢!这就是分层架构啊!”。就这样,咱们把“分层架构”这样一个内涵和外延都极大的抽象概念和一个具体的Demo划了等号,从而也变成了故事中那我的——咱们言分层架构必称DAL、BLL,咱们作项目必然依照PetShop方式架构……
咱们确实被PetShop“毒害”了。但这不是微软的错,更不是PetShop的错,就像在故事中,咱们不能把罪责归咎于奶牛场管理员或那头奶牛。错在咱们本身!
当微软给咱们PetShop时,咱们应该在脑中清醒认识到:这是一个分层架构的Demo。而不是理解成了“这就是分层架构”。咱们应该钻研、思考,从而抓住分层架构的本质,但是咱们没有。
与其说咱们是被PetShop“毒害”了,倒不如说咱们是被本身、被本身那种不良的学习习惯毒害了。咱们仅看表象,仍是只看了一个表象,而后就冒然对分层架构盖棺定论。而没能透过想象看本质。因此,咱们一样犯了“一叶障目”的错误。
以上的错误,笔者也曾经犯过!因此,在下文中,我想和朋友们一块儿分享一下我在检讨本身的过程当中,悟出的一些心得体会,但愿能借此帮助更多朋友尽快走出“一叶障目”。
洞悉分层的本质
咱们能够讨论如何分层,能够讨论分层的利弊,能够讨论分层有没有价值……但在这一切一切讨论以前,咱们要先弄清楚一件事:分层的本质是什么?或者说:分层是怎么来的?若是这个问题不明晰,那么咱们其余的讨论犹如“浮沙之上筑高台”,再精辟的言辞,若是没有一个牢固的基础,也是站不住脚的。
想要了解分层的本质,就不得不说说分工。分工能够说是劳动生产力上最大的改良,最初分工的好处体如今“比较优点”上,因为各司其职,每一个人能够从事其最擅长的劳动,再加上单纯劳动所带来的劳动熟练度提高和减小了更换劳动时的损失,使得劳动生产率大幅提高。然而,随着社会的发展,咱们发现某些特殊形式的分工不但能够提升生产力,还有另外一些好处!为了理解这些好处,咱们举个实际的例子。
今天是六一国际儿童节,一位母亲想给她的女儿买一个奶油蛋糕做为礼物。咱们知道,蛋糕须要面粉、须要鸡蛋、须要牛奶等等,还需呀通过一系列复杂的加工和包装过程,可是这位母亲不须要关心这些,她只要去附近的超市直接买就好了。而超市里既没有养鸡场,也没有奶牛场,更没有种小麦的农民伯伯和烘焙蛋糕的工人师傅。这个简单的“买蛋糕”场景,大约能够用下图表示。
图一、制做蛋糕的分工
图1大约说明了一个蛋糕是如何从到达顾客手里的。能够看到,制做蛋糕不是一个单一的劳动,须要许多的分工,若是自底向上看,主要的分工包括:基础物质资料的种植生产、原料加工、蛋糕加工、商业销售。并非全部分工都如上图这样,上图所示的分工,有一些特色,下面总结一下。
1.下层不知道上层的存在。例如奶牛厂生产牛奶,它没必要知道牛奶被拿去作什么,可能被奶油厂收购去作奶油,也可能被雪糕厂收购了作雪糕,也可能被收购去作奶糖,总之,它只管完成本身的职责——生产牛奶,而对于它的上层一无所知。一样,奶油加工厂只管生产奶油,它没必要知道奶油被拿去作蛋糕仍是作摩卡咖啡。
2.每一层仅仅知道它的下一层(最后一层除外,由于最后一层没有下一层),而不知道另外的下层。例如,蛋糕厂只需知道从面粉厂、奶油厂和鸡蛋厂提取面粉、奶油、鸡蛋就好了,而没必要关心面粉是怎么来了、奶油是怎么来的这些问题。
能够说,符合以上两点的分工就是分层架构的思想来源。下面说的稍微正式一点。
所谓分层思想,就是这样一种分工:它将系统按不一样的职责组织成有序的层次。其中,除最上层外,每一层仅提供若干服务供其相邻的上层使用,但不知道上层的存在;除最下层外,每一层仅调用其临近下层的服务。
因此,所谓“分层思想”,不过是一种特殊的分工形式。而计算机软件架构中的分层思想,是将这一思想应用于软件开发中的特例,而PetShop所使用的“DAL+BLL+PL”的方式,又不过是将这一思想应用于软件开发中的特例的特例。例如,若是某个系统的业务很简单,仅仅是增删改查,那么BLL就没有做用,“DAL+PL”的方式就能够很好完成,这也是很好的分层架构。再如,若是某个系统的业务很复杂,须要先规格化,再作运算,再作整理,那么“DAL+规格化层+计算层+整理层+PL”这种五层架构也是很合理的啊。若是某个系统BLL所暴露的接口太繁杂,那么使用Facade模式在BLL和PL之间加一个“Facade Service Layer”也是很正常的。再者,若是某个系统不须要数据存取功能,例如计算器程序,咱们只是想把表示和业务(计算功能)分开,那么就没有DAL了,“BLL+PL”就是合理的。因此,用分层的思想进行架构,本质是“将系统按不一样职责组织成有序层次……”这一段话描述的,而不是简单“将系统分红DAL+BLL+PL”,更不是“按PetShop的方式进行架构”。
下面,摘录一段Fowler在《Patterns of Enterprise Application Architecture》中对分层的定义:
When thinking of a system in terms of layers, you imagine the principal subsystem in the software arranged in some form of layer cake,where each layer rests on lower layer. In this scheme the higher layer uses various services defined by lower layer,but lower layer is unaware of the higher layer. Furthemore, each layer usally hides its lower layers from the layers above.
——Martin Fowler, 《Patterns of Enterprise Application Architecture》, P17
大体译文以下:
当咱们说一个系统是分层架构的时候,你能够把这个软件想象成一个有不少层的蛋糕的样子,其中每一层放在它的下一层上。较高层使用诸多较低层定义和提供的服务,但较低层并无察觉较高层的存在。另外,每一层都会对其上层隐藏更低的层。
——马丁 福勒, 《企业应用架构模式》, P17
可是,这里有一点须要声明:虽说“DAL+BLL+PL”不等价于分层架构,而仅仅是一种实例。但同时咱们要清楚的认识到,这个方式之因此如此流行,以致于微软的官方示例都这样架构,是由于对于许多系统,特别是大中型MIS系统,这种架构方式是应该优先考虑的。在这一节中,笔者绝对没有对“DAL+BLL+PL”进行批判的意思,相反,当开发系统时,这种方式能够优先考虑,而后能够根据系统的特色,进行必定得改良。笔者在本节所强调的是:不能把“DAL+BLL+PL”看作分层架构的本质,更不能和“分层架构”这个思想概念划等号。
分层架构的利弊分析
在理解了分层架构的本质的基础上,咱们才能够放心大胆的对分层架构进行利弊分析。废话少讲,这一节咱们直接切入正题。
分层架构的优势以下:
1.分离开发人员的关注。因为某一层仅仅调用其相邻下一层所提供的服务,因此,只要本层的API和相邻下一层的API定义完整,开发人员在开发某一层时就能够像关注集中于这一层所用的思想、模式、技术,这样,就等同于将分工带来的生产力提升优点引入软件开发。又如买蛋糕的例子,做为超市,只要知道下层API(如何从蛋糕厂获取蛋糕)和本层须要实现的API(把蛋糕销售给客户),就能够制定本身的业务模式很策略计划了,而没必要关心如何种小麦、如何磨面粉、如何作奶油、如何作蛋糕等。这样,超市只需进行商业运做,而没必要进行产业运做,如此专注,必然提升业务水平。
2.无损替换。想象一下,若是某家奶牛场倒闭了,奶油加工厂也要跟着倒闭吗?固然不会,它能够迅速更换一家奶牛场,由于各个奶牛场均可以实现“提供牛奶”这项服务。再譬如,若是某天国家出台政策,要求全部奶油厂必须从审查合格的奶牛场引进原料,刚好某奶油厂的合做牛奶供应商没能经过审查,那么,只要换一家经过审查的合做就好了。并且奶油厂内部的各个环节一动不用动,由于不一样的奶牛场均可以提供“供应牛奶”这个服务。而若是奶油厂本身养牛生产牛奶,一旦遇到这个政策,还得本身去有关部门进行审查,调整相应业务流程,牵一发而动全身。程序中一样的道理,最常据说的可能就是迁移数据库了。
3.下降了系统间的依赖。仍是蛋糕那个例子,若是某天蛋糕厂内部换机器了,或业务流程调整了,请问顾客须要关心吗?显然不用,由于顾客只调用超市提供的服务。而超市为顾客隐藏了下面全部产业细节。若是每个顾客买同样商品,都要了解这个商品从原料生产到成型再到销售的一系列细节,岂不累死了。换作程序中,就如表示层只管调用业务层的服务,至于业务层下还有几层?各类数据是怎么来的?怎么存的?是真实的仍是捏造的?都不须要了解,这大大下降了系统各职责之间的依赖。
4.复用。例如,你能够去这个超市买东西,我也能够去这个超市买东西。蛋糕厂能够从面粉厂提取面粉,馒头厂也能够。这样,一样的层就能够为不一样的上层提供服务,达到了复用的目的。具体到程序中,例如气象局制做发布了一个“Service Layer”,用于提供天气预告信息。这样新浪、搜狐这些网站能够利用这个服务层提供的服务,制做天气预告页面,QQ也能够利用这个服务在它的聊天工具上添加天气预告,你本身作一个软件须要用到天气预告功能,也能够调用气象台的“Service Layer”。
说罢优势,再来谈谈分层架构的弊端:
1.级联修改问题。这个问题在现实中很差比喻,但在程序中相信不少朋友都明白。例如,一我的事管理系统,原本查看人员信息只能分页查看,而如今,须要增长一个功能:在分页的同时还能分部门。例如,能够查看“销售部的前50我的”,这样,为了这个功能全部层都须要修改。
2.性能问题。原本直来直去的操做,如今要层层传递,势必形成性能的降低。就如在购买蛋糕的例子中。顾客在享受分工带来的便利时,也要承受因为不一样层的部门分布各地而形成的蛋糕价格上升,这是由于分层增长了成本,如运输、不一样层间部门的协调管理成本等。
纵观以上分析,分层架构有利有弊。这是必定得,世上任何事物都有利弊,因此,把“分层架构捧上天”和“一棍子打死”这两种作法都是不明智也是不科学的。对待分层架构,咱们的态度应当是明晰其本质和利弊,而后根据具体状况作出理性的分析和抉择。
从上面的分析能够看出,分层架构能够下降层内变化的成本,而对于API的变化很是敏感。如在级联修改中提到的“在分页的同时还能分部门”的新需求,就是对API进行的变更。API的变更对于分层架构是致命的,修改起来难度很是大。因此,一个简单的判断法则就是:
若是您的系统层内频繁变更(甚至整层替换)可能性很大,而API变更可能性很小,就使用分层;而若是API可能会频繁变更,那就要谨慎使用分层架构了。
后面的话 其实,我想说的主要内容,就是前面三节了。不过仍是有些话,想和你们唠叨唠叨。 这篇文章,不是一篇技术文章,因此通篇不提技术细节,而只是想帮你们澄清对分层的误解。最近看了不少对分层架构(或三层架构)的探讨,其中以批判居多,有的甚至认为分层就是个没用的垃圾东西。我想,产生这种想法的人,大体通过了如下阶段:据说分层,粗略学习分层、模仿使用分层、用得十分不爽、出来批判。 其实,任何技术都是客观的,都没有错误,错误在人,是人没有正确使用,或没有用到合适的地方。就像咱们不能批判刀片不适合劈叉,也不能批判柴刀不适合刮胡子。一项技术想要发挥威力,关键要正确运用,而要正确运用,就须要有深厚的功底,须要咱们努力学习,勤于思考。这不是一朝一夕的事情,要有持久的毅力。咱们要争取作一个善于用功、善于把握事物本质的人,而不是一个用刀片劈柴、用柴刀刮胡子,而后大骂刀片和柴刀都是垃圾的人。 分层思想历来就不是软件架构中首先提出来的,咱们每天上网用到的网络,都遵循OSI七层协议,网络结构的设计是分层思想合理应用的一个典范。另外,在许多其余工程技术领域,分层思想也是很广泛的。因此,不要把分层当成计算机人士甚至软件开发人士独有的能力,相对那些领域,将分层应用于软件架构的技术还很不成熟,还有许多事情等待咱们去作。