也谈分层
最近在网上看了很多关于架构的文章,比较流行的是三层架构。我也来凑个热闹,跟着扯一扯分层。
我们从大处往小处说,先说,什么是架构?架构是一系列相关的抽象模式,用于指导大型软件系统各方面的设计。它描述一个软件系统从整体到部分的最高层次的抽象划分。直接认为架构就是系统草图也不为过。
根据我们关注的角度不同,架构大概有三种:
1、逻辑架构,主要描述软件系统中元件之间的关系,例如用户界面,数据库,业务逻辑元件等等
2、物理架构,主要描述软件元件是如何安装到硬件上的。
3、系统架构,主要描述系统的非功能性特征,如可扩展性、可靠性、强壮性、灵活性、性能等。
可以看到,系统架构师必须具备软件和硬件两方面的过硬能力,还得有丰富的经验。
怎么架构一个软件系统,这个时候,通常会用到分层。
可以说,分层就是为了架构一个好的系统,主要体现在以下几个方面(网上主流观点):
1、降低耦合,可以降低层与层之间的依赖。上一层仅依赖于下一层,如果测试下一层没有问题,那么问题就只可能出现在本层了。这样又利于应对需求变更,有利于排错,有利于后期的维护。
2、简化问题复杂度,各层分工明确,例如OSI七层模型和简化的tcpip协议的四层模型。把一个复杂问题分解,达到化繁为简的效果。但是,这是针对系统大小而言的,如果一个很小的系统,也可能会把简单问题复杂化。
3、有利于团队开发,分工合作。开发人员可以只关注整个结构中的其中某一层,三层架构中,基本可以将工作分为界面设计人员、业务实现人员、数据库设计人员。可以根据每个人根据自己的特长只关注这一层的设计和实现,不必理会其他层。只要各层接口在开发前规定好,那么各层可以独立开发,进化或维护。
4、有利于有利于标准化,在开发过程中可以将每层的代码进行规范,固定开发语言的风格,可以忽略数据库的差异,设计完善的数据访问层可以将数据库的差异完全屏蔽,可以快速安全地实现数据库的切换等
5、可以很容易的用新的实现来替换原有层次的实现,便于系统维护/升级。各层间通过接口解耦,接口与实现分离,从而可以非常方便的替换掉实现,或者升级实现等。
6、逻辑复用。例如原来基于B/S开发的程序现在要改成C/S,那么只要业务层的接口没有改变,那么业务层和数据层都可以直接复用。在如,只要数据访问层接口不变,那么使用便可以有对不同数据库的实现。
7、方便部署。将各层开发成组件,则可以独立部署。分层可以把各层部署在不同的地方,实现分布式系统。
针对以上七点谈谈自己的见解;
个人认为分层最大的好处和关键就在于一个方面:隔离!或者说是:抽象,然后隔离!
分层的最理想化的结果是实现层与层之间的互不依赖的内部实现,说白了,分层的目的就是为了隔离,这样可以带来灵活性,封装性,可维护性,可扩展性,可靠性。这都是相对而言,因为不可避免的会在性能,复杂性,架构难度等方面带来不利影响,这种影响可大可小,不能绝对化。
只有隔离,才能团队开发,分工合作,只要各层接口在开发前规定好,那么各层可以独立开发,进化或维护。
只有隔离,才能方便部署,不同类型的组件据它们所在的层分布在不同的机器上,共同组成一个基于组件的分布式系统,实现多层分布式企业的应用。
只有隔离,才能最大限度的实现复用,只要业务层的接口没有改变,那么业务层和数据层都可以直接复用。
只有隔离,才能有更好的可维护性,各层间通过接口解耦,接口与实现分离,从而可以非常方便的替换掉实现,或者升级实现等。
谈到可维护性,再多说一点,设计软件系统是为了开发出一个易于被人理解的软件,不能理解的东西必然无法正确的建设和维护,这个软件如果很容易被人理解,那么它一定易于维护,相反,如果你自认为软件设计得很好,但不被人理解,自然也没人可以维护(当然,如果你可以跟这个软件耗一辈子,你能理解,你就能维护,不用管别人理不理解,反正维护也是你一个人的事情)。而高内聚,低耦合只是被多数人认可的设计原则,因为多数人认为它帮助我们设计出易于理解,易于维护的软件。关键在于:化繁为简,如果将来有更好的原则可以实现化繁为简,那么人们肯定抛弃高内聚低耦合,选用更好的方式。
貌似所有关于分层的文章最后的结论都大同小异,无外乎:具体问题具体分析,即:分不分层,怎么分层要是具体情况而定。
这里引用网友的一段话,认为有些道理。
分层也好,模型也好,只是手段,目的是实现业务逻辑。用什么手段促成目的,是由业务需求决定的。业务需求不复杂,用存储过程足以解决的,不见得分层设计好,不见得领域模型好。个人的学习过程中追求什么样的设计风格是个人偏好问题,项目开发中实在是要具体分析,盲目套用耦合,不降反升,效率不高反低,维护不便反繁。
我再给加上一点,软件设计,要考虑成本(当然得替公司考虑成本啦),成本主要由两方面决定,开发成本和维护成本。分层如果能减少这两处的成本,例如:通过分层,可以合理复用减少开发代码量,减少了开发成本;同时降低了模块耦合,便于后期的维护,从而减少了维护成本,这个时候可以选择分层。如果视需求情况,我们通过分层(前提不考虑分层不够合理),不能减少这两方面的成本,反而把提高了系统的复杂度,出现了代码冗余,性能降低等等,就没有必要分层了。