谈谈架构分层

news2025/1/16 13:43:23

大家好,我是易安!

在系统从0到1的阶段,为了让系统快速上线,我们通常是不考虑分层的。但是随着业务越来越复杂,大量的代码纠缠在一起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动一处就牵一发而动全身等问题。

这时,对系统进行分层就会被提上日程,那么我们要如何对架构进行分层?今天我们就来讲一讲

什么是分层架构

软件架构分层在软件工程中是一种常见的设计方式,它是将整体系统拆分成N个层次,每个层次有独立的职责,多个层次协同提供完整的功能。

我们在刚刚成为程序员的时候,会被“教育”说系统的设计要是“MVC”(Model-View-Controller)架构。它将整体的系统分成了Model(模型),View(视图)和Controller(控制器)三个层次,也就是将用户视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是一种标准的软件分层架构。

alt

另外一种常见的分层方式是将整体架构分为表现层、逻辑层和数据访问层:

  • 表现层,顾名思义嘛,就是展示数据结果和接受用户指令的,是最靠近用户的一层;
  • 逻辑层里面有复杂业务的具体实现;
  • 数据访问层则是主要处理和存储之间的交互。

这是在架构上最简单的一种分层方式。其实,我们在不经意间已经按照三层架构来做系统分层设计了,比如在构建项目的时候,我们通常会建立三个目录:Web、Service和Dao,它们分别对应了表现层、逻辑层还有数据访问层。

alt

除此之外,如果我们稍加留意,就可以发现很多的分层的例子。比如我们在大学中学到的OSI网络模型,它把整个网络分成了七层,自下而上分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

工作中经常能用到TCP/IP协议,它把网络简化成了四层,即链路层、网络层、传输层和应用层。每一层各司其职又互相帮助,网络层负责端到端的寻址和建立连接,传输层负责端到端的数据传输等,同时相邻两层还会有数据的交互。这样可以隔离关注点,让不同的层专注做不同的事情。

alt

Linux文件系统也是分层设计的,从下图你可以清晰地看出文件系统的层次。在文件系统的最上层是虚拟文件系统(VFS),用来屏蔽不同的文件系统之间的差异,提供统一的系统调用接口。虚拟文件系统的下层是Ext3、Ext4等各种文件系统,再向下是为了屏蔽不同硬件设备的实现细节,我们抽象出来的单独的一层——通用块设备层,然后就是不同类型的磁盘了。

我们可以看到,某些层次负责的是对下层不同实现的抽象,从而对上层屏蔽实现细节。比方说VFS对上层(系统调用层)来说提供了统一的调用接口,同时对下层中不同的文件系统规约了实现模型,当新增一种文件系统实现的时候,只需要按照这种模型来设计,就可以无缝插入到Linux文件系统中。

alt

那么,为什么这么多系统一定要做分层的设计呢?答案是分层设计存在一定的优势。

分层设计的好处

分层的设计可以简化系统设计,让不同的人专注做某一层次的事情。 想象一下,如果你要设计一款网络程序却没有分层,该是一件多么痛苦的事情。

因为你必须是一个通晓网络的全才,要知道各种网络设备的接口是什么样的,以便可以将数据包发送给它。你还要关注数据传输的细节,并且需要处理类似网络拥塞,数据超时重传这样的复杂问题。当然了,你更需要关注数据如何在网络上安全传输,不会被别人窥探和篡改。

而有了分层的设计,你只需要专注设计应用层的程序就可以了,其他都可以交给下面几层来完成。

再有,分层之后可以做到很高的复用。 比如,我们在设计系统A的时候,发现某一层具有一定的通用性,那么我们可以把它抽取独立出来,在设计系统B的时候使用起来,这样可以减少研发周期,提升研发的效率。

最后一点,分层架构可以让我们更容易做横向扩展。 如果系统没有分层,当流量增加时我们需要针对整体系统来做扩展。但是,如果我们按照上面提到的三层架构将系统分层后,就可以针对具体的问题来做细致的扩展。

比如说,业务逻辑里面包含有比较复杂的计算,导致CPU成为性能的瓶颈,那这样就可以把逻辑层单独抽取出来独立部署,然后只对逻辑层来做扩展,这相比于针对整体系统扩展所付出的代价就要小得多了。

如何来做系统分层

说了这么多分层的优点,那么当我们要做分层设计的时候,需要考虑哪些关键因素呢?

在我看来,最主要的一点就是你需要理清楚每个层次的边界是什么。你也许会问:“如果按照三层架构来分层的话,每一层的边界不是很容易就界定吗?”

没错,当业务逻辑简单时,层次之间的边界的确清晰,开发新的功能时也知道哪些代码要往哪儿写。但是当业务逻辑变得越来越复杂时,边界就会变得越来越模糊,给你举个例子。

任何一个系统中都有用户系统,最基本的接口是返回用户信息的接口,它调用逻辑层的GetUser方法,GetUser方法又和User DB交互获取数据,就像下图左边展示的样子。

这时,产品提出一个需求,在APP中展示用户信息的时候,如果用户不存在,那么要自动给用户创建一个用户。同时,要做一个HTML5的页面,HTML5页面要保留之前的逻辑,也就是不需要创建用户。这时逻辑层的边界就变得不清晰,表现层也承担了一部分的业务逻辑(将获取用户和创建用户接口编排起来)。

alt

那我们要如何做呢?参照阿里巴巴Java开发手册,我们可以将原先的三层架构细化成下面的样子:

alt

我来解释一下这个分层架构中的每一层的作用。

  • 终端显示层:各端模板渲染并执行显示的层。当前主要是 Velocity 渲染,JS 渲染, JSP 渲染,移动端展示等。
  • 开放接口层:将Service层方法封装成开放接口,同时进行网关安全控制和流量控制等。
  • Web层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
  • Service层:业务逻辑层。
  • Manager 层:通用业务处理层。这一层主要有两个作用,其一,你可以将原先Service层的一些通用能力下沉到这一层,比如与缓存和存储交互策略,中间件的接入;其二,你也可以在这一层封装对第三方接口的调用,比如调用支付服务,调用审核服务等。
  • DAO层:数据访问层,与底层 MySQL、Oracle、HBase 等进行数据交互。
  • 外部接口或第三方平台:包括其它部门 RPC 开放接口,基础平台,其它公司的 HTTP 接口。

在这个分层架构中主要增加了Manager层,它与Service层的关系是:Manager层提供原子的服务接口,Service层负责依据业务逻辑来编排原子接口。

以上面的例子来说,Manager层提供创建用户和获取用户信息的接口,而Service层负责将这两个接口组装起来。这样就把原先散布在表现层的业务逻辑都统一到了Service层,每一层的边界就非常清晰了。

除此之外,分层架构需要考虑层次之间一定是相邻层互相依赖,数据的流转也只能在相邻的两层之间流转。

我们还是以三层架构为例,数据从表示层进入之后一定要流转到逻辑层,做业务逻辑处理,然后流转到数据访问层来和数据库交互。那么你可能会问:“如果业务逻辑很简单的话可不可以从表示层直接到数据访问层,甚至直接读数据库呢?”

其实从功能上是可以的,但是从长远的架构设计考虑,这样会造成层级调用的混乱,比方说如果表示层或者业务层可以直接操作数据库,那么一旦数据库地址发生变更,你就需要在多个层次做更改,这样就失去了分层的意义,并且对于后面的维护或者重构都会是灾难性的。

分层架构的不足

任何事物都不可能是尽善尽美的,分层架构虽有优势也会有缺陷,它最主要的一个缺陷就是增加了代码的复杂度。

这是显而易见的嘛,明明可以在接收到请求后就可以直接查询数据库获得结果,却偏偏要在中间插入多个层次,并且有可能每个层次只是简单地做数据的传递。有时增加一个小小的需求也需要更改所有层次上的代码,看起来增加了开发的成本,并且从调试上来看也增加了复杂度,原本如果直接访问数据库我只需要调试一个方法,现在我却要调试多个层次的多个方法。

另外一个可能的缺陷是,如果我们把每个层次独立部署,层次间通过网络来交互,那么多层的架构在性能上会有损耗。这也是为什么服务化架构性能要比单体架构略差的原因,也就是所谓的“多一跳”问题。

那我们是否要选择分层的架构呢? 答案当然是肯定的。

你要知道,任何的方案架构都是有优势有缺陷的,天地尚且不全何况我们的架构呢?分层架构固然会增加系统复杂度,也可能会有性能的损耗,但是相比于它能带给我们的好处来说,这些都是可以接受的,或者可以通过其它的方案解决的。 我们在做决策的时候切不可以偏概全。

总结

今天我讲了分层架构的优势和不足,以及我们在实际工作中如何来对架构做分层。分层架构是软件设计思想的外在体现,是一种实现方式。我们熟知的一些软件设计原则都在分层架构中有所体现。掌握这些设计思想会自然而然地明白分层架构设计的妙处,同时也能帮助我们做出更好的设计方案。

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501219.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IIS6.0和网络管理软件SNMPc

一.IIS6.0 IIS 6.0提供了更为方便的安装/管理功能和增强的应用环境、基于标准的分布协议、改进的性能表现和扩展性,以及更好的稳定性和易用性。其服务组件包括: ①WWW服务。WWW是图形最为丰富的Internet服务。Web具有很强的链接能力,支持协…

软考中级——系统集成项目管理工程师(20天冲刺)

PV:计划价值(计划要成的价值) EV:挣值(实际做了的事儿的价值) AC:实际成本(实际花出去多少钱) SV:进度偏差EV-PV(项目提前或者落后的进度)>0项目进度超前<0项目进度落后 CV:成本偏差EV-AC(项目预算的号空成者盈利)>0成本节约<0成本超支 SPI:进度绩效指数EV/PV(挣值…

创建VUE2 前端以及后端的交互

创建vue2项目 1.javascript–>vue(不要勾选)–>安装element-ui(组件 | Element)–>执行指令&#xff08;npm i element-ui -S&#xff09;–>在main.js中引入&#xff08;import ElementUI from ‘element-ui’; ​ import ‘element-ui/lib/theme-chalk/index.c…

JavaWeb:Web 的基本概念、Tomcat 服务器、Http 详解、Maven 的下载安装步骤、模仿一个 Servlet

文章目录 JavaWeb - 01一、基本概念1、静态 Web2、动态 Web3、Web 应用程序4、三个技术 二、Web 服务器三、Tomcat 详解四、发布一个 Web 网站五、Http 详解1. Http 请求&#xff08;1&#xff09;请求行&#xff08;2&#xff09;消息头 2. Http 响应&#xff08;1&#xff09…

sourceTree离线环境部署

目录 1、下载sourceTree安装包&#xff0c;打开之后弹出注册界面&#xff08;需要去国外网站注册&#xff09;2、使用技术手段跳过注册步骤3、打开安装包进行安装 注&#xff1a;建议提前安装好git 1、下载sourceTree安装包&#xff0c;打开之后弹出注册界面&#xff08;需要去…

27 - 两数、三数、四数问题

文章目录 1. 两数之和2. 三数之和3. 最接近的三数之和4. 四数之和5. 四数相加 1. 两数之和 在遍历数组的时候只需要在map中去查询是否有个目前元素target - numbers[i]匹配的数值&#xff0c;如果有&#xff0c;就找到匹配对&#xff0c;如果没有就把目前遍历的元素放入map中&a…

融合有序,创造无限——解密力扣“合并两个有序数组”

本篇博客会讲解力扣“88. 合并两个有序数组”这道题&#xff0c;这是题目链接。 其实&#xff0c;有经验的朋友一看到这个题目的名字&#xff0c;应该就明白了&#xff0c;这玩意和归并排序脱不了干系。下面我们来审题&#xff1a; 输出示例如下&#xff1a; 以下是一些提…

3.是人就能学会的Spring源码教学-IOC容器的核心实现原理

是人就能学会的Spring源码教学-IOC容器的核心实现原理 我们学习Spring源码的动力&#xff0c;估计大部分人都是因为面试中会问到吧。 那么我们今天就以面试问Spring来开头。 关于Spring&#xff0c;在面试的时候一般会问到的两个最基础的问题。 第一个什么是IOC&#xff1f…

技术控,看这里,一款支持断点调试的数据科学工具

数据科学是一门利用统计学、机器学习、数据挖掘、数据可视化等技术和方法&#xff0c;从数据中提取知识和信息的交叉学科。自上世纪60年代&#xff0c;统计学家John W.Tukey首次提出“数据分析”&#xff08;Data Analysis&#xff09;的概念起&#xff0c;数据科学已历经了几十…

ASEMI代理ADUM131E1BRWZ-RL原装ADI车规级ADUM131E1BRWZ-RL

编辑&#xff1a;ll ASEMI代理ADUM131E1BRWZ-RL原装ADI车规级ADUM131E1BRWZ-RL 型号&#xff1a;ADUM131E1BRWZ-RL 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;SOIC-16-300mil 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;16 工作温度…

基于springboot的“智慧食堂”设计与实现(源码等)

摘要 随着Internet的发展&#xff0c;人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化&#xff0c;网络化和电子化。网上管理&#xff0c;它将是直接管理“智慧食堂”系统的最新形式。本xx是以构建“智慧食堂”系统为目标&#xff0c;使用java技术制作…

智能仿写软件-智能伪原创改写软件

智能仿写工具&#xff1a;营销创意的必备利器 在当今快节奏和不断发展的商业环境中&#xff0c;企业营销人员需要在短时间内产生大量有创意和高质量的内容。因此&#xff0c;智能仿写工具作为营销策略的一种创新方法而出现&#xff0c;可以帮助企业的写作团队更快速地生成文章…

【软考数据库】第八章 数据库SQL语言

目录 8.1 SQL语言概述 8.2 数据库定义 8.2.1 创建表(create table) 8.2.2 修改表 (alter table) 8.2.3 删除表 (drop table) 8.2.4 索引 8.2.5 视图 8.3 数据操作 8.3.1 查询语句格式 8.3.2 分组查询 8.3.3 其他操作 8.3.4 约束 8.4 数据授权 8.4.1 授权grant 8…

数据库索引的原理,为什么要用 B+树,为什么不用二 叉树?

1、B树和B树 一般来说&#xff0c;数据库的存储引擎都是采用B树或者B树来实现索引的存储。首先来看B树&#xff0c;如图所士 B树是一种多路平衡树&#xff0c;用这种存储结构来存储大量数据&#xff0c;它的整个高度会相比二叉树来说&#xff0c;会矮很多。 而对于数据库而言…

RFID系统在物流仓储中的应用

RFID系统是一种无线识别技术&#xff0c;最近成为物流仓储行业的热门话题。本文将介绍RFID系统在物流仓储中的应用&#xff0c;包括如何使用RFID标签进行物流管理&#xff0c;如何使用RFID技术提高仓库的安全性&#xff0c;并细述RFID技术在物流仓储中的优势。除此之外&#xf…

ArrayList快速失败机制

文章目录 一、什么是快速失败机制二、例子三、底层原理四、解决方法五、快速失败机制的一个小bug 一、什么是快速失败机制 ArrayList实现了一种称为快速失败(fail-fast)的机制,该机制在并发修改时会抛出ConcurrentModificationException异常。 这种机制的实现原理是:ArrayList…

机器学习案例 | 通过EBG学习概念cup

基于解释的学习(explanation-basedlearning)可简称为解释学习&#xff0c;是20世纪80年代中期开始兴起的一种机器学习方法。解释学习根据任务所在领域知识和正在学习的概念知识&#xff0c;对当前实例进行分析和求解&#xff0c;得出一个表征求解过程的因果解释树&#xff0c;以…

spark2

18Spark中stage的划分 和 shuffle的概念 Stage的划分是根据宽依赖&#xff0c;当触发action算子时&#xff0c;按照从后往前的回溯算法&#xff0c;当遇到会发生shuffle算子的时候&#xff0c;就会切分stage。 Stage的划分本质是shuffle,即当遇到会发生shuffle算子的时…

E. Sergey and Subway(思维 + dp)

Problem - E - Codeforces Sergey Semyonovich 是 N 市县的市长&#xff0c;他一直在思考如何进一步改善 Nkers 的生活。不幸的是&#xff0c;几乎所有可以做的事情都已经完成了&#xff0c;白天他已经没有更多的想法&#xff08;他现在喜欢在晚上睡觉&#xff09;。然而&#…

MySQL 中的 distinct 和 group by 的区别

目录 distinct用法distinct多列去重 group by的使用单列去重多列去重 distinct和group by原理隐式排序基于上述原因&#xff0c;Mysql在8.0时&#xff0c;对此进行了优化更新&#xff1a; 结论推荐group by的原因 在语义相同&#xff0c;有索引的情况下&#xff1a;group by和d…