技术开发 频道

你了解分层架构吗?给被PetShop“毒害”的朋友

    1.下层不知道上层的存在。例如奶牛厂生产牛奶,它不必知道牛奶被拿去做什么,可能被奶油厂收购去做奶油,也可能被雪糕厂收购了做雪糕,也可能被收购去做奶糖,总之,它只管完成自己的职责——生产牛奶,而对于它的上层一无所知。同样,奶油加工厂只管生产奶油,它不必知道奶油被拿去做蛋糕还是做摩卡咖啡。

    2.每一层仅仅知道它的下一层(最后一层除外,因为最后一层没有下一层),而不知道另外的下层。例如,蛋糕厂只需知道从面粉厂、奶油厂和鸡蛋厂提取面粉、奶油、鸡蛋就行了,而不必关心面粉是怎么来了、奶油是怎么来的这些问题。

    可以说,符合以上两点的分工就是分层架构的思想来源。下面说的稍微正式一点。所谓分层思想,就是这样一种分工:它将系统按不同的职责组织成有序的层次。其中,除最上层外,每一层仅提供若干服务供其相邻的上层使用,但不知道上层的存在;除最下层外,每一层仅调用其临近下层的服务。

    所以,所谓“分层思想”,不过是一种特殊的分工形式。而计算机软件架构中的分层思想,是将这一思想应用于软件开发中的特例,而PetShop所使用的“DAL+BLL+PL”的方式,又不过是将这一思想应用于软件开发中的特例的特例。例如,如果某个系统的业务很简单,仅仅是增删改查,那么BLL就没有作用,“DAL+PL”的方式就可以很好完成,这也是很好的分层架构。再如,如果某个系统的业务很复杂,需要先规格化,再做运算,再做整理,那么“DAL+规格化层+计算层+整理层+PL”这种五层架构也是很合理的啊。如果某个系统BLL所暴露的接口太繁杂,那么使用Facade模式在BLL和PL之间加一个“FacadeServiceLayer”也是很正常的。再者,如果某个系统不需要数据存取功能,例如计算器程序,我们只是想把表示和业务(计算功能)分开,那么就没有DAL了,“BLL+PL”就是合理的。所以,用分层的思想进行架构,本质是“将系统按不同职责组织成有序层次……”这一段话描述的,而不是简单“将系统分成DAL+BLL+PL”,更不是“按PetShop的方式进行架构”。

    下面,摘录一段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可能会频繁变动,那就要谨慎使用分层架构了。

    后面的话

    其实,我想说的主要内容,就是前面三节了。不过还是有些话,想和大家唠叨唠叨。

    这篇文章,不是一篇技术文章,所以通篇不提技术细节,而只是想帮大家澄清对分层的误解。最近看了很多对分层架构(或三层架构)的探讨,其中以批判居多,有的甚至认为分层就是个没用的垃圾东西。我想,产生这种想法的人,大致经过了以下阶段:听说分层,粗略学习分层、模仿使用分层、用得十分不爽、出来批判。

    其实,任何技术都是客观的,都没有错误,错误在人,是人没有正确使用,或没有用到合适的地方。就像我们不能批判刀片不适合劈叉,也不能批判柴刀不适合刮胡子。一项技术想要发挥威力,关键要正确运用,而要正确运用,就需要有深厚的功底,需要我们努力学习,勤于思考。这不是一朝一夕的事情,要有持久的毅力。我们要争取做一个善于用功、善于把握事物本质的人,而不是一个用刀片劈柴、用柴刀刮胡子,然后大骂刀片和柴刀都是垃圾的人。

    分层思想从来就不是软件架构中首先提出来的,我们天天上网用到的网络,都遵循OSI七层协议,网络结构的设计是分层思想合理应用的一个典范。另外,在许多其他工程技术领域,分层思想也是很普遍的。所以,不要把分层当成计算机人士甚至软件开发人士独有的能力,相对那些领域,将分层应用于软件架构的技术还很不成熟,还有许多事情等待我们去做。

    最后强烈推荐一本书:Martin Fowler的《Patterns of EnterpriseApplicationArchitecture》,相信看完这本书,对于分层思想的理解和分层中具体模式的运用决策都会有大幅提高。你会明白,原来分层不是只有“DAL”、“BLL”,原来分层还有怎么多内在的东西。

1
相关文章