你了解.Net 分层架构吗?
洞悉分层的本质
我们可以讨论如何分层,可以讨论分层的利弊,可以讨论分层有没有价值……但在这一切一切讨论之前,我们要先弄清楚一件事:分层的本质是什么?或者说:分层 是怎么来的?如果这个问题不明晰,那么我们其他的讨论犹如“浮沙之上筑高台”,再精辟的言辞,如果没有一个牢固的基础,也是站不住脚的。
想要了解分层的本质,就不得不说说分工。分工可以说是劳动生产力上最大的改良,最初分工的好处体现在“比较优势”上,由于各司其职,每个人可以从事其最擅 长的劳动,再加上单纯劳动所带来的劳动熟练度提升和减少了更换劳动时的损失,使得劳动生产率大幅提升。然而,随着社会的发展,我们发现某些特殊形式的分工 不但可以提高生产力,还有另一些好处!为了理解这些好处,我们举个实际的例子。
今天是六一国际儿童节,一位母亲想给她的女儿买一个奶油蛋糕作为礼物。我们知道,蛋糕需要面粉、需要鸡蛋、需要牛奶等等,还需呀经过一系列复杂的加工和包 装过程,但是这位母亲不需要关心这些,她只要去附近的超市直接买就行了。而超市里既没有养鸡场,也没有奶牛场,更没有种小麦(资讯,行情)的农民伯伯和烘 焙蛋糕的工人师傅。这个简单的“买蛋糕”场景,大约可以用下图表示:
图1. 制作蛋糕的分工
图1大约说明了一个蛋糕是如何从到达顾客手里的。可以看到,制作蛋糕不是一个单一的劳动,需要许多的分工,如果自底向上看,主要的分工包括:基础物质资料的种植生产、原料加工、蛋糕加工、商业销售。并不是所有分工都如上图这样,上图所示的分工,有一些特点,下面总结一下。
1.下层不知道上层的存在。例如奶牛厂生产牛奶,它不必知道牛奶被拿去做什么,可能被奶油厂收购去做奶油,也可能被雪糕厂收购了做雪糕,也可能被收 购去做奶糖,总之,它只管完成自己的职责——生产牛奶,而对于它的上层一无所知。同样,奶油加工厂只管生产奶油,它不必知道奶油被拿去做蛋糕还是做摩卡咖 啡。
2.每一层仅仅知道它的下一层(最后一层除外,因为最后一层没有下一层),而不知道另外的下层。例如,蛋糕厂只需知道从面粉厂、奶油厂和鸡蛋厂提取面粉、奶油、鸡蛋就行了,而不必关心面粉是怎么来了、奶油是怎么来的这些问题。
可以说,符合以上两点的分工就是分层架构的思想来源。下面说的稍微正式一点。所谓分层思想,就是这样一种分工:它将系统按不同的职责组织成有序的层次。其 中,除最上层外,每一层仅提供若干服务供其相邻的上层使用,但不知道上层的存在;除最下层外,每一层仅调用其临近下层的服务。
所以,所谓“分层思想”,不过是一种特殊的分工形式。而计算机软件架构中的分层思想,是将这一思想应用于软件开发中的特例,而PetShop所使用的 “DAL+BLL+PL”的方式,又不过是将这一思想应用于软件开发中的特例的特例。例如,如果某个系统的业务很简单,仅仅是增删改查,那么BLL就没有 作用,“DAL+PL”的方式就可以很好完成,这也是很好的分层架构。再如,如果某个系统的业务很复杂,需要先规格化,再做运算,再做整理,那么 “DAL+规格化层+计算层+整理层+PL”这种五层架构也是很合理的啊。如果某个系统BLL所暴露的接口太繁杂,那么使用Facade模式在BLL和 PL之间加一个“FacadeServiceLayer”也是很正常的。再者,如果某个系统不需要数据存取功能,例如计算器程序,我们只是想把表示和业务 (计算功能)分开,那么就没有DAL了,“BLL+PL”就是合理的。所以,用分层的思想进行架构,本质是“将系统按不同职责组织成有序层次……”这一段 话描述的,而不是简单“将系统分成DAL+BLL+PL”。
下面,摘录一段Fowler在《Patterns of EnterpriseApplicationArchitecture》中对分层的定义:
When thinking of a system in terms of layers, you imaginetheprincipal subsystem in the software arranged in some form oflayercake,where each layer rests on lower layer. In this schemethehigher layer uses various services defined by lower layer,butlowerlayer is unaware of the higher layer. Furthemore, each layerusallyhides its lower layers from the layers above.
——Martin Fowler, 《Patterns of EnterpriseApplicationArchitecture》, P17
大致译文如下:
当我们说一个系统是分层架构的时候,你可以把这个软件想象成一个有很多层的蛋糕的样子,其中每一层放在它的下一层上。较高层使用诸多较低层定义和提供的服务,但较低层并没有察觉较高层的存在。另外,每一层都会对其上层隐藏更低的层。
——马丁 福勒, 《企业应用架构模式》, P17
但是,这里有一点需要声明:虽然说“DAL+BLL+PL”不等价于分层架构,而仅仅是一种实例。但同时我们要清楚的认识到,这个方式之所以如此流行,以 至于微软的官方示例都这样架构,是因为对于许多系统,特别是大中型MIS系统,这种架构方式是应该优先考虑的。在这一节中,笔者绝对没有对 “DAL+BLL+PL”进行批判的意思,相反,当开发系统时,这种方式可以优先考虑,然后可以根据系统的特点,进行一定得改良。笔者在本节所强调的是: 不能把“DAL+BLL+PL”看做分层架构的本质,更不能和“分层架构”这个思想概念划等号。
分层架构的利弊分析
在理解了分层架构的本质的基础上,我们才可以放心大胆的对分层架构进行利弊分析。废话少讲,这一节我们直接切入正题。
分层架构的优点如下:
1.分离开发人员的关注。
由于某一层仅仅调用其相邻下一层所提供的服务,所以,只要本层的API和相邻下一层的API定义完整,开发人员在开发某一层时就可以像关注集中于这一层所 用的思想、模式、技术,这样,就等同于将分工带来的生产力提高优势引入软件开发。又如买蛋糕的例子,作为超市,只要知道下层API(如何从蛋糕厂获取蛋 糕)和本层需要实现的API(把蛋糕销售给客户),就可以制定自己的业务模式很策略计划了,而不必关心如何种小麦、如何磨面粉、如何做奶油、如何做蛋糕 等。这样,超市只需进行商业运作,而不必进行产业运作,如此专一,必然提高业务水平。
2.无损替换。
想象一下,如果某家奶牛场倒闭了,奶油加工厂也要跟着倒闭吗?当然不会,它可以迅速更换一家奶牛场,因为各个奶牛场都可以实现“提供牛奶”这项服务。再譬 如,如果某天国家出台政策,要求所有奶油厂必须从审查合格的奶牛场引进原料,恰好某奶油厂的合作牛奶供应商没能通过审查,那么,只要换一家通过审查的合作 就行了。而且奶油厂内部的各个环节一动不用动,因为不同的奶牛场都可以提供“供应牛奶”这个服务。而如果奶油厂自己养牛生产牛奶,一旦遇到这个政策,还得 自己去有关部门进行审查,调整相应业务流程,牵一发而动全身。程序中同样的道理,最常听说的可能就是迁移数据库了。
3.降低了系统间的依赖。
还是蛋糕那个例子,如果某天蛋糕厂内部换机器了,或业务流程调整了,请问顾客需要关心吗?显然不用,因为顾客只调用超市提供的服务。而超市为顾客隐藏了下 面所有产业细节。如果每一个顾客买一样商品,都要了解这个商品从原料生产到成型再到销售的一系列细节,岂不累死了。换做程序中,就如表示层只管调用业务层 的服务,至于业务层下还有几层?各种数据是怎么来的?怎么存的?是真实的还是捏造的?都不需要了解,这大大降低了系统各职责之间的依赖。
4.复用。
例如,你可以去这个超市买东西,我也可以去这个超市买东西。蛋糕厂可以从面粉厂提取面粉,馒头厂也可以。这样,同样的层就可以为不同的上层提供服务,达到 了复用的目的。具体到程序中,例如气象局制作发布了一个“ServiceLayer”,用于提供天气预告信息。这样新浪、搜狐这些网站可以利用这个服务层 提供的服务,制作天气预告页面,QQ也可以利用这个服务在它的聊天工具上添加天气预告,你自己做一个软件需要用到天气预告功能,也可以调用气象台的 “ServiceLayer”。
说罢优点,再来谈谈分层架构的弊端:
1.级联修改问题。这个问题在现实中不好比喻,但在程序中相信很多朋友都明白。例如,一个人事管理系统,本来查看人员信息只能分页查看,而现在,需要增加 一个功能:在分页的同时还能分部门。例如,可以查看“销售部的前50个人”,这样,为了这个功能所有层都需要修改。
2.性能问题。本来直来直去的操作,现在要层层传递,势必造成性能的下降。就如在购买蛋糕的例子中。顾客在享受分工带来的便利时,也要承受由于不同层的部门分布各地而造成的蛋糕价格上升,这是因为分层增加了成本,如运输、不同层间部门的协调管理成本等。
纵观以上分析,分层架构有利有弊。这是一定得,世上任何事物都有利弊,所以,把“分层架构捧上天”和“一棍子打死”这两种做法都是不明智也是不科学的。对待分层架构,我们的态度应当是明晰其本质和利弊,然后根绝具体情况做出理性的分析和抉择。
从上面的分析可以看出,分层架构可以降低层内变化的成本,而对于API的变化非常敏感。如在级联修改中提到的“在分页的同时还能分部门”的新需求,就是对 API进行的变动。API的变动对于分层架构是致命的,修改起来难度非常大。所以,一个简单的判断法则就是:如果您的系统层内频繁变动(甚至整层替换)可 能性很大,而API变动可能性很小,就使用分层;而如果API可能会频繁变动,那就要谨慎使用分层架构了。