洋葱架构、三层架构及两者区别
前言
洋葱架构它的名称来源于洋葱的层次结构,即软件代码的各层次之间的关系。在这种架构中,应用程序的各个组件通过一系列层次结构被逐层包裹在一起,形成一个类似于洋葱的结构。
一、经典三层架构
三层架构是一种软件设计模式,将应用程序分成三个不同的层次:表示层、业务逻辑层和数据访问层。这三层分别负责不同的功能,它们互相独立,松耦合,这样可以减少修改代码的影响范围。
1.1、功能分类
-
表示层(Presentation Layer):这是用户界面层。它包含了展示给用户的各种UI元素,如文本框、按钮、菜单、图表、表格、列表等等。这一层负责接收用户输入,呈现输出结果,同时将用户请求向下传递到业务逻辑层。
-
业务逻辑层(Business Logic Layer):这是应用程序的中心,它包含了实现软件业务逻辑的代码。它是应用程序的核心,负责处理和执行业务逻辑、数据处理、验证、安全性、事务管理等方面的代码。这一层与展示层和数据层进行交互。
-
数据访问层(Data Access Layer):这一层处理与数据存储交互的问题。数据层负责管理数据、访问数据库、读取和写入数据、以及与存储过程和存储在数据库中的对象交互等等。数据层实现了数据的持久化,并将结果返回给业务逻辑层。
1.2、优点:
-
易于维护:三层架构将应用程序拆分为三个逻辑部分,使得不同层次的代码分离清晰,易于维护和管理。
-
可重用性高:三层架构中每个组件都独立运作,因此可以很容易地重用这些组件,并在不同的应用程序中使用它们。
-
灵活性强:三层架构将系统按照逻辑结构划分,因此可以对不同层次的代码进行单独修改,而无需改变整个系统。
-
可扩展性强:三层架构中每个层次都可以独立扩展,因此可以根据需求对系统进行灵活的扩展。
1.3、缺点:
-
性能问题:三层架构在不同的层之间进行数据传输和转换,这可能会导致性能问题,特别是在高并发情况下。
-
数据访问问题:在三层架构中,数据访问通常是通过数据访问层来进行的。这使得数据访问层的开发和维护变得非常困难。
-
不适合小型项目:由于三层架构的复杂性和性能问题,它不适合小型项目。在小型项目中,客户端/服务器架构可能更加适合。
二、洋葱架构
该架构的主要思想是将应用程序代码分成多个层次,每个层次都有不同的职责和依赖关系,并且每个层次都依赖于下一个内层的层次,同时也不会依赖于更外层的层次,通过这种方式,应用程序的耦合度可以得到有效的降低,便于开发和测试。
2.1、主要功能分类
具体分层由具体业务决定,大体分层如下:
-
外层:用户界面和展示层。负责将数据呈现给用户并接受用户的输入。
-
控制层:负责接收来自用户界面的请求,调用服务层的方法,并将结果返回给用户界面。
-
服务层:负责实现业务逻辑,通过调用数据访问层来获取或更新数据。
-
数据访问层:负责访问数据存储层,包括数据库、文件系统等。
-
数据存储层:负责实际存储数据。
2.2、优点:
-
松耦合:洋葱架构使用依赖反转、接口隔离等设计模式,将不同的层之间的耦合降到最低程度,从而使得系统更加灵活,易于维护和扩展。
-
分离关注点:洋葱架构将应用程序分成不同的层,每层都有自己的关注点。这样可以使得每层的代码更加集中,便于维护和修改,同时也可以避免代码耦合,提高代码的可复用性和可测试性。
-
清晰的代码层次结构:洋葱架构使得应用程序的代码层次结构更加清晰,使得应用程序的整个开发和维护过程更加简单。
2.3、缺点:
-
复杂性:洋葱架构的实现需要开发人员具备一定的技术水平和经验,同时也需要较高的代码质量和可维护性,因此在开发过程中可能会面临较大的挑战。
-
性能问题:洋葱架构中的每一层都会增加一定的性能开销,从而导致系统的性能损失。因此,在实现洋葱架构时需要仔细考虑每一层的设计和实现。
-
对开发人员的要求较高:洋葱架构需要开发人员具备扎实的基础知识和较高的技术水平,因此可能不适合初级开发人员使用。
两者区别
洋葱架构和三层架构都是常用的软件架构模式,它们的区别主要表现在以下几个方面:
-
结构不同:三层架构通常由表示层、业务逻辑层和数据访问层组成,每层之间的依赖关系是线性的。而洋葱架构则由具体业务功能将应用程序划分为多层,在洋葱架构中,每个层都依赖于它们内部和外部的层。
-
责任分工不同:在三层架构中,表示层主要负责处理用户界面和响应用户输入,业务逻辑层处理业务逻辑和规则,数据访问层负责访问和管理数据。在洋葱架构中,每个层都有更明确的职责,应用层定义应用程序的入口点和业务逻辑,领域层处理核心业务逻辑和规则,基础设施层提供基础设施支持,比如数据库、文件和网络等。
-
依赖注入方式不同:三层架构通常使用依赖注入容器来管理对象之间的依赖关系。而洋葱架构则更加注重依赖反转,使用依赖倒置原则,通过构造函数进行依赖注入,来解耦和降低层次之间的耦合性。
总的来说,洋葱架构以面向切面编程和依赖反转为核心,更加符合现代软件开发的复杂需求;而三层架构则是相对传统的软件架构模式,适用于简单、直接的软件开发需求。
相关文章:
洋葱架构、三层架构及两者区别
前言 洋葱架构它的名称来源于洋葱的层次结构,即软件代码的各层次之间的关系。在这种架构中,应用程序的各个组件通过一系列层次结构被逐层包裹在一起,形成一个类似于洋葱的结构。 一、经典三层架构 三层架构是一种软件设计模式,…...

JavaEE进阶学习:Spring 的创建和使用
Spring 就是⼀个包含了众多工具方法的 IoC 容器。既然是容器那么它就具备两个最基本的功能: 将对象存储到容器(Spring)中从容器中将对象取出来 接下来使用 Maven 方式来创建一个 Spring 项目,创建 Spring 项目和 Servlet 类似&a…...
音视频项目—基于FFmpeg和SDL的音视频播放器解析(十四)
介绍 在本系列,我打算花大篇幅讲解我的 gitee 项目音视频播放器,在这个项目,您可以学到音视频解封装,解码,SDL渲染相关的知识。您对源代码感兴趣的话,请查看基于FFmpeg和SDL的音视频播放器 如果您不理解本…...

Tomcat无法映射到activiti-app导致activiti无法启动页面
原因之一:JDK版本与Tomcat版本不匹配,jdk8 yyds 我使用的是JDK11,Tomcat是9.0的,都是最新的,但还是不行,最后JDK改为8,tomcat的cmd后台没有报错,activiti-pp也可以正常访问了,很神奇…...
c语言常见的面试问题
在C语言编程中,面试官可能会询问你以下一些常见问题: 什么是C语言? C语言是一种通用的、过程式的计算机编程语言,由Dennis Ritchie在1972年创建。它是Unix操作系统的核心语言,也是许多其他编程语言(如Go、…...

image图片之间的间隙消除
多个图片排列展示,水平和垂直方向的间隔如何消除 垂直方向 vertical-align 原因: vertical-align属性主要用于改变行内元素的对齐方式,行内元素默认垂直对齐方式是基线对齐(baseline) 这是因为图片属于行内元素&…...

asp.net心理健康管理系统VS开发sqlserver数据库web结构c#编程计算机网页项目
一、源码特点 asp.net 心理健康管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 系统视频链接 https://www.bilibili.com/video/BV19w411H7P4/ 二、功能介绍 本系统使用Microsoft Visual Studio…...

CnosDB有主复制演进历程
分布式存储系统的复杂性涉及数据容灾备份、一致性、高并发请求和大容量存储等问题。本文结合CnosDB在分布式环境下的演化历程,分享如何将分布式理论应用于实际生产,以及不同实现方式的优缺点和应用场景。 分布式系统架构模式 分布式存储系统下按照数据复…...

【前沿学习】美国零信任架构发展现状与趋势研究
转自:美国零信任架构发展现状与趋势研究 摘要 为了应对日趋严峻的网络安全威胁,美国不断加大对零信任架构的研究和应用。自 2022 年以来,美国发布了多个零信任战略和体系架构文件,开展了多项零信任应用项目。在介绍美国零信任战略…...
Toolformer论文阅读笔记(简略版)
文章目录 引言方法限制结论 引言 大语言模型在zero-shot和few-shot情况下,在很多下游任务中取得了很好的结果。大模型存在的限制:无法获取最新的信息、无法进行精确的数学计算、无法理解时间的推移等。这些限制可以通过扩大模型规模一定程度上解决&…...

Pytorch torch.dot、torch.mv、torch.mm、torch.norm的用法详解
torch.dot的用法: 使用numpy求点积,对于二维的且一个二维的维数为1 torch.mv的用法: torch.mm的用法 torch.norm 名词解释:L2范数也就是向量的模,L1范数就是各个元素的绝对值之和例如:...

Jave 定时任务:使用Timer类执行定时任务为何会发生任务阻塞?如何解决?
IDE:IntelliJ IDEA 2022.2.3 x64 操作系统:win10 x64 位 家庭版 JDK: 1.8 文章目录 一、Timer类是什么?二、Timer类主要由哪些部分组成?1.TaskQueue2. TimerThread 三、示例代码分析四、自定义TimerTask为什么会发生任务相互阻塞的…...

Visual Studio Code配置c/c++环境
Visual Studio Code配置c/c环境 1.创建项目目录2.vscode打开项目目录3.项目中添加文件4.文件内容5.配置编译器6.配置构建任务7.配置调试设置 1.创建项目目录 d:\>mkdir d:\c语言项目\test012.vscode打开项目目录 3.项目中添加文件 4.文件内容 #include <iostream> u…...
漏洞利用工具的编写
预计更新网络扫描工具的编写漏洞扫描工具的编写Web渗透测试工具的编写密码破解工具的编写漏洞利用工具的编写拒绝服务攻击工具的编写密码保护工具的编写情报收集工具的编写 漏洞利用工具是一种常见的安全工具,它可以利用系统或应用程序中的漏洞来获取系统权限或者窃…...
ChatGPT之父被OpenAI解雇
首席技术官 Mira Murati 任命临时首席执行官领导 OpenAI;山姆阿尔特曼(Sam Altman)离开公司。 阿尔特曼先生的离职是在董事会经过深思熟虑的审查程序之后进行的,审查程序得出的结论是,他在与董事会的沟通中始终不坦诚…...

linux中利用fork复制进程,printf隐藏的缓冲区,写时拷贝技术,进程的逻辑地址与物理地址
1.prinf隐藏的缓冲区 1.思考:为什么会有缓冲区的存在? 2.演示及思考? 1).演示缓存区没有存在感 那为什么我们感觉不到缓冲区的存在呢?我们要打印东西直接就打印了呢? 我们用代码演示一下: 比如打开一个main.c,输入内容如下: #include <stdio.h>int main(){printf…...

java游戏制作-拼图游戏
一.制作主界面 首先创建一个Java项目命名为puzzlegame 结果:】 二.设置界面 代码: 三.初始化界面 代码: 优化代码: 四.添加图片 先在Java项目中创建图片文件夹,将图片导入其中 管理图片: 五.打乱图片顺序...
使用sklearn报AttributeError: ‘NoneType‘ object has no attribute ‘split‘
错误原因 在使用scikit-learn的时候报AttributeError: NoneType object has no attribute split Exception ignored on calling ctypes callback function: <function _ThreadpoolInfo._find_modules_with_dl_iterate_phdr..match_module_callback at 0x7fb757978160> T…...
C++学习 --map
目录 1, 什么是map 2, 创建map 2-1, 标准数据类型 2-2, 自定义数据类型 2-3, 其他创建方式 3, 操作map 3-1, 赋值 3-2, 插入元素(insert) 3-2-1, 插入标准数据类…...

基于Qt QList和QMap容器类示例
## QList<T> QList<T>容器是一个数组列表,特点如下: 1.大多数情况下可以用QList。像prepend()、append()和insert()这种操作,通常QList比QVector快的多。这是因为QList是基于index标签存储它的元素项在内存中(虽然内存不连续,这点与STL的list 是一样的),比…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...