摘要:分层架构简单而高效,业界已经有很多成熟的应用,对那些项目刚刚起步,架构师们还没想好要采用哪种架构模式的系统而言,这是非常适合的。

前言

软件刚出现的时候,还是大型计算机的年代,一个软件系统一般都只会运行在一台机器上。随着软硬件技术的革新,计算机体积和成本逐渐变小,此时工程师们发现一个软件系统只运行在单台机器上会存在各种瓶颈。如果将系统按照功能划分成前端和后端,分别部署在两台服务器上,问题得到了缓解,于是便有了Client/Server架构的出现。

随后,个人电脑的兴起带动了众多富桌面应用(rich desktop application)的出现,它们基于操作系统上的user interface开发,数据则是存储在单独部署的database server上,通过标准的网络协议进行数据通信。这种Desktop + Database Server的架构和C/S架构一样,同属两层架构(two-tier architecture)。

随着90年代互联网的迅速崛起,Browser + Web Server + Database Server的组合也渐渐风靡。Browser为表现层,提供用户交互界面;Web Server为业务层,处理具体的业务逻辑;Database Server为数据层,存储系统数据。三个层次各司其职,这也是大家最熟悉的三层架构(three-tier architecture)。

上述的几种架构模式都属于分层架构(layered architecture)的范畴,分层架构并没有限定一定得有多少个层次,层次的数量可以根据应用场景灵活控制,因此也被称为n-tier architecture。它结构简单,基于此架构进行系统开发成本也很低(很多公司在组织结构上划分为前端工程师、后端工程师、DBA,根据康威定律,这天然就具备了分层架构开发的良好条件),因此它在业界备受欢迎。如果你的团队还不确定选择什么样的架构,又或者为了践行敏捷宣言中的“just starts coding“,那么分层架构会是一个不错的选择

架构视图

在分层架构中,组件根据功能被划分在不同的层次上,虽然层次的数量和类型并没有被限制,但大多数的分层架构都由以下4层组成:表现层(presentation)、业务层(business)、持久层(persistence)和数据层(database),如下图所示。在一些简单的系统中,持久层的逻辑(如SQL)被嵌入到业务层中,形成了经典的三层架构;而在一些复杂的系统中,也会根据具体的业务划分为五层甚至更多的层次。

分层架构的标准逻辑分层

前文所述的表现层等4个层次都是逻辑的划分方法,在实际部署时,一般会有下图所示的几种部署形态。形态1中,表现层、业务层和持久层为一个部署单元,而数据层则单独部署,具体表现为一个独立部署的数据库或文件系统;形态2中,表现层被分离出单独部署,业务层和持久层组成一个部署单元,数据层依旧是单独部署的数据库或文件系统;形态3中,包括数据层在内的4层全都在同一个部署单元内,常见于业务简单的系统,它们往往使用的是嵌入式数据库或内存数据库。

分层架构的部署形态

分层架构中的每一层都扮演着各自的角色,比如表现层负责处理所有的用户请求和浏览器交互,而业务层则负责执行每次请求下的特定业务逻辑;表现层无需担心从哪里获取用户数据,它只需要将数据以特定的格式在浏览器上显示即可。同样地,业务层也无需关心用户数据从何而来以及如何呈现,它只需从持久层中取出数据,执行特定的业务逻辑(比如聚合数据),然后将结果返回给表现层。

每一层都是特定行为的抽象,这样的职责划分,使得组织能够快速高效地创建出责任模型,围绕各层打造开发团队

层间隔离

分层架构中的每一层可以是封闭的或者开放的,封闭意味着当一个请求自顶向下在层间传递时,它不能跳过任意的一层。比如,当表现层接收到请求之后,它必须先后经过业务层和持久层才能到达数据层,如下图所示。

封闭的分层架构

对于简单的数据获取类请求,如果让表现层能够直接访问数据层获取数据,无疑是最简单高效的。也即是让业务层和持久层变成开放状态,允许请求在层间传递时跳过此层。那么,究竟是封闭好,还是开放好呢?要解答这个问题,就要回到层间隔离的出发点上。

所谓的层间隔离,旨在降低一个层次上的变化对其他层次的组件的影响,简单来说,就是每个层次对其他层次的功能知道的越少越好。为了达到层间隔离的目的,就需要将每个层次置为封闭的状态。假设表现层能够直接访问持久层,那么持久层的变化将会直接影响到业务层和表现层,这加剧了层间的耦合,导致系统变化的代价高昂。

层间隔离可以降低层次变化对系统的影响,凡事没有绝对,在某些的场景,将特定的层次置为开放的状态也不失为一件好事。考虑以下例子,业务层中存在着一些共享组件承载着业务层公共的功能(比如日志类、审计类、日期和字符串工具类等)。现在有一项架构决策要求表现层不能直接访问这些共享组件,但矛盾的是,原则上表现层是可以直接访问业务层的,这种需要违反原则的决策将会很难落地。

业务层中的共享组件

一种解决方法是,新增一个服务层,该层包含了业务层的这些共享组件。因为业务层是关闭的状态,故表现层也就不能访问到这些共享组件了。然而,新增的服务层必须置为开放状态,否则业务层将无法直接访问持久层。新增一个服务层并置为开放状态,这样既落地了架构决策,也不会影响到原有的功能,一举两得。

在分层架构中新增一个层次

一些注意事项

在使用分层架构时,需要注意以下两点:

1、做好模块的划分

为分层架构做好模块划分主要是为后续的架构演进做好准备,比如在业务复杂到一定程度后演进为微服务架构时,各个模块可以很自然地演进为微服务。为此,应该避免出现类的继承层次过深的现象,这会导致代码严重的耦合,不利于后续的架构演进。

2、避免掉进sinkhole反模式的陷阱

所谓sinkhole反模式指的是请求只是简单地路过各个层次,并没有做一些业务处理。

比如,表现层接收到一个获取基本用户数据(姓名、地址等)的请求后将它传递到业务层;然而,业务层并没有做任何的业务处理,直接将请求传递到持久层;持久层也仅仅是构造了一个简单的SQL语句,向数据层查询用户数据;最后,数据按照原路返回到表现层,中途没有经过任何的数据汇聚、转换等操作。

sinkhole反模式会导致很多不必要的对象实例化开销,从而增大了系统的内存消耗,并且影响了性能

然而,一个系统多多少少都会存在一些sinkhole反模式场景,要判断一个系统是否已经彻底掉进sinkhole反模式的陷阱,主要还是看这类业务请求所占的百分比。根据20-80法则,当系统中有超过80%的业务请求是sinkhole类请求时,表示系统已经掉进sinkhole反模式的陷阱,这从侧面也说明该系统已经不再适合分层架构,是时候考虑架构演进了。

综合得分

分层架构的综合得分

从综合得分上看,分层架构的Overall cost和Simplicity得分很高,这很大程度上得益于分层架构本身是单体架构,少了很多分布式系统才有的复杂性。但这样导致Deployability得分很低,因为3行代码的改动就足以造成整个系统的重新部署。Testability得分不高也是这个原因,整系统的重新上线通常都需要将测试用例全部执行一遍,多了不少额外的工作量。

Elasticity、Fault tolerance、Scalability这些都是单体架构天然的劣势,自然地,分层架构在这些方面得分都很低。另外,sinkhole反模式的存在也拉低了分层架构在Performance上的得分。

总结

分层架构简单而高效,业界已经有很多成熟的应用,对那些项目刚刚起步,架构师们还没想好要采用哪种架构模式的系统而言,这是非常适合的。在实现分层架构时,我们需要合理地设置各个层次的封闭或开放状态,做好层间隔离,同时也要避免掉进sinkhole反模式陷阱。随着业务的不断扩张,分层架构在可维护性、可测试性、可扩展性等上的短板也会逐步被放大,此时就需要考虑往其他架构模式演进了。

点击关注,第一时间了解华为云新鲜技术~

架构的变迁,从分层架构先聊起相关推荐

  1. 【车载以太网】【架构】以太网的分层架构_汽车以太网标准化组织介绍

    年关已近,想必很多小伙伴都在忙着做各种总结,今天小编也想借此机会给大家简单总结一下汽车以太网相关的那些组织. 话说2013年,采用博通BroadR-Reach技术的宝马X5量产,标志着汽车以太网技术的 ...

  2. DDD—分层架构、洋葱架构、六边形架构

    一.DDD分层架构 DDD分层架构中有很重要的依赖原则:每层只能与位于下方的层发生耦合,类似于网络的7层或TCP/IP的4层模型架构,每一层各司其职,并且只关心向下一层的实现,而不会出现各层耦合. D ...

  3. 架构师必备,了解分层架构中缓存那点事儿

    戳蓝字"CSDN云计算"关注我们哦! 作者:贺志兵 无论是CDN缓存加速,还是CPU的三级缓存,又或者是在如今互联网时代流量红利所带来的高并发结构客户端,而不得不使用缓存架构.缓存 ...

  4. DDD分层架构最佳实践

    还在单体应用的时候就是分层架构一说,我们用得最多的就是三层架构.而现在已经是微服务时代,在微服务架构模型比较常用的有几个,例如:整洁架构,CQRS(命令查询分离)以及六边形架构.每种架构模型都有自己的 ...

  5. 这 3 种 DDD 分层架构的模式,你掌握了么?

    -     前言    - 在讨论DDD分层架构的模式之前,我们先一起回顾一下DDD和分层架构的相关知识. -     DDD 的基本概念     - DDD(Domain DrivenDesign, ...

  6. Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课

    Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课 本课程采用Q Q群直播方式进行直播,价值99元视频课程免费直播.完整的基于Swift项目实战,手把手教你做一个Swift版i ...

  7. DDD分层架构的三种模式

    本文来说下DDD分层架构的三种模式 文章目录 概述 DDD 分层架构 模式一:四层架构 模式二:五层架构 模式三:六边形架构 本文小结 概述 在讨论DDD分层架构的模式之前,我们先一起回顾一下DDD和 ...

  8. 分层架构、六边形架构、CQRS架构模式解读

    DDD DDD(Domain Driven Design,领域驱动设计)作为一种软件开发方法,它可以帮助我们设计高质量的软件模型.在正确实现的情况下,我们通过DDD完成的设计恰恰就是软件的工作方式. ...

  9. 分层结构的生活例子_详解软件分层架构设计、工作原理、实例以及具体架构

    概述 今天的内容主要来自<软件架构模式>第一章,觉得还不错,所以分享给大家. 分层架构 分层架构是一种很常见的架构模式,它也叫N层架构.这种架构是大多数Jave EE应用的实际标准,因此很 ...

最新文章

  1. jquery入门与实践案例教程
  2. 递归调用cl_crm_oi_docx_transform_rt=process_node_cc
  3. Element.shadowRoot
  4. html window 属性,html中window对象top 、self 、parent 等属性
  5. SignalR--Web客户端
  6. RabbitMQ实现(并发)多线程处理消息
  7. 函数-在函数里修改列表数据
  8. php中strtotime函数,PHP中strtotime函数用法举例
  9. php我的世界网页地图,探险家地图 - Minecraft Wiki,最详细的官方我的世界百科
  10. Android面试题(一)
  11. Google Drive 转存别人分享的文件到自己的网盘
  12. 亚马逊将为语音助手研发AI芯片 欲追赶苹果
  13. 解决Office Word复制粘贴时自动加空格的问题
  14. 网站优化-减少DNS查询
  15. 我的UC/OS,我做主
  16. 从底层分区开始做一个干净的Windows10
  17. 全网最详细泛微Ecology9安装教程及安装包
  18. 中间件_Redis_02_Redis的数据类型
  19. MS8412音频光纤同轴接口转换器
  20. pdfbox将多页pdf转成多张长图片

热门文章

  1. 万字长文,SpringSecurity
  2. Bootstrap 按钮的尺寸
  3. php实现数字英文验证码,PHP英文数字验证码生成类
  4. Linux tcp三次握手,解读TCP三次握手
  5. multipartfile 获取音频时长_QQ音乐移动端加入倍速播放,蓄力长音频发展 | 产品观察...
  6. iis服务器文件上传大小限制,windows服务器中iis限制文件大小方法
  7. vscode比较整个文件夹_vscode开发ROS1(5)-ROS工程目录结构
  8. CentOS 7.2安装zabbix 3.0 LTS
  9. RCurl网络数据抓取
  10. pku2182: Lost Cows