程序员必知的7种软件架构模式

2023-10-27

架构模式是对给定上下文的软件架构中常见问题的一种通用的可复用的解决方案。

一种模式就是特定上下文的问题的一种解决方案。

然而,很多开发者至今还对各种软件架构模式之间的差别搞不清,甚至对其所知甚少。

大体上,主要有下面这7种架构模式:

  1. 分层架构

  2. 多层架构

  3. 管道 - 过滤器架构

  4. 客户端 - 服务器架构

  5. 模型 - 视图 - 控制器架构

  6. 事件驱动架构

  7. 微服务架构

1

分层架构模式

最常见的架构模式就是分层架构或者称为 n 层架构。

大部分软件架构师、设计师和开发者都对这个架构模式非常熟悉。尽管对于层的数量和类型没有具体限制,但大部分分层架构主要由四层组成:展现层、业务层、持久层和数据库层,如下图所示。

一个很流行的 n 层架构示例

 1 上下文 

所有复杂的系统都会经历独立地发展和衍化系统各个部分的需要。出于这个原因,系统开发者需要对关注点进行清晰且条理分明的分离,以便系统的各个模块可以独立地开发和维护。

 2 问题 

软件需要以这样一种方式分割:各个模块可以独自开发和衍化,各自部分之间的交互非常少,支持可移植性、可修改性和复用性。

 3 方案 

为了实现关注点分离,分层模式将软件分割成各个单元(称为“层”)。每一层都是一组模块,提供了一组高内聚的服务。其使用必须是单向的。层将一组软件作为一个完整的分区,每个分区暴露一个公开接口。

  • 第一个概念是,每一层都有特定的角色和职责。例如,展现层负责处理所有的用户界面。分层架构的这种关注点分离,让构建高效的角色和职责非常简单。

  • 第二个概念是,分层架构模式是一个技术性的分区架构,而非一个领域性的分区架构。它们是由组件组成的,而不是领域。

  • 最后一个概念是,分层架构中的每一层都被标记为封闭或者开放。封闭层意味着请求从一层移到另一层,它必须通过它正下面的这一层才能达到下面这一层的再下一层。请求不能跳过任何层。

封闭层和请求访问

 4 弱点 

分层会导致性能下降。这种模式不适合高性能应用程序,因为经过架构中的多层来实现一个业务请求的效率是不高的。

分层还会增加系统的前期成本和复杂性。

 5 用途 

我们应该将这种方式应用于小型简单的应用程序或网站。对于预算和时间非常紧张的场景,这是一个不错的选择。

2

多层模式

 1 方案 

一个多层模式示例:消费者网站 J2EE

许多系统的执行结构被组织成一系列逻辑组件分组。每个分组被称为一个层。

 1 上下文 

在一个分布式部署中,通常需要将系统的基础设施分到不同的子集中。

 2 问题 

我们如何将系统分割到多个计算上独立的执行结构:由一些通信媒介连接的软件和硬件组?

 3 弱点 

大量前期成本和复杂性。

 4 用途 

用在分布式系统中。

3

管道-过滤器架构

软件架构中反复出现的一种模式是管道 - 过滤器(pipe-filter)模式。

管道过滤器模式

 1 上下文 

许多系统需要转换从输入到输出的离散数据流。许多类型转换在实践中重复出现,因此将其创建成独立的可复用的部分,这是比较理想的。

 2 问题 

这些系统需要被分割成可复用的松耦合的组件,组件之间拥有简单通用的交互机制。这样它们就可以灵活地相互结合。这些通用松耦合的组件就很容易复用。那些独立的组件可以并行执行。

 3 方案 

这种架构中的管道构成了过滤器之间的通信通道。第一个概念是,由于性能原因,每个管道都是非定向的和点对点的,接受来自一个源的输入并经常直接输出到另外一个源。

在这种模式中,有如下四种过滤器。

  • producer(source):一个过程的起点。

  • transformer (map):对一些或所有数据进行转换。

  • tester (reduce):测试一个或多个条件。

  • consumer (sink):终点。

 4 弱点 

不太适合交互性的系统,因为它们的转换特性。

过多的解析和反解析会导致性能损失,也会增加编写过滤器本身的复杂性。

 5 用途 

管道 - 过滤器架构用于各种应用程序,特别是简化单项处理的任务,例如 EDI、ETL 工具。

编译器:连续的过滤器执行词法分析、语法分析、语义分析和代码生成。

4

客户端-过滤器架构

 1 上下文 

有许多共享资源和服务是大量分布式的客户端希望访问的,我们希望控制访问或服务质量。

 2 问题 

通过管理一组共享资源和服务,我们可以通过分解公共服务并在单个位置或少数位置进行修改来提高可修改性和复用性。我们想要通过在将资源本身分布在多个物理服务器上的同时集中控制这些资源和服务,来提高可伸缩性和可用性。

 3 方案 

在客户端 - 服务器模式中,组件和连接器具有特定的行为。

称为“客户端”的组件将请求发送到称为“服务器”的组件,然后等待回复。

服务器组件接收到客户端的请求并向其发送回复。

 4 弱点 

服务器会成为性能瓶颈和单点故障位置。

在系统建成后,关于功能位置(在客户端还是在服务器)的决策通常是复杂的而且变动成本很大。

 5 用途 

对于有许多组件(客户端)发送请求到另外一些提供服务的组件(服务器)的系统,我们可以使用客户端 - 服务器模式来建模这个系统的一部分:在线应用程序,例如电子邮件、共享文档或银行服务。

5

模型-视图-控制器架构(MVC)

 1 上下文 

用户界面通常是一个交互性应用程序的最频繁被修改的部分。用户通常希望从不同的视角查看数据,例如柱状图或者饼图。这些表示形式都应该反映数据当前的状态。

 2 问题 

用户界面功能如何独立于应用程序功能,同时还还对用户输入或底层应用程序数据的更改做出响应?

当底层应用程序数据更改时,如何创建、维护和协调用户界面的多个视图?

 3 方案 

模型 - 视图 - 控制器(model-view-controller,即 MVC)模式将应用程序功能分为以下三种类型的组件:

  • 模型,包含应用程序的数据。

  • 视图,显示部分底层数据并与用户交互。

  • 控制器,在模型和视图之间进行中介并管理状态更改的通知。

 4 弱点 

对于简单的用户界面,其复杂性并不值得这么做。

模型、视图和控制器抽象可能不适用于某些用户界面工具包。

 5 用途 

MVC 是网站或移动应用程序开发用户界面常用的一种架构模式。

6

事件驱动架构

 1 上下文 

需要提供计算和信息资源来处理传入的应用程序生成的独立异步事件,这种方式可以随着需求的增加而扩展。

 2 问题 

构建分布式系统,这个系统可以服务异步到达的事件相关信息,并且能从简单小型扩展到复杂大型。

 3 方案 

为事件处理部署独立的事件进程或处理器。到达的事件进入队列。调度程序根据调度策略从队列中拉取事件并将它们分配到合适的事件处理器。

 4 弱点 

性能和错误恢复可能是问题。

 5 用途 

使用这个方案的电商应用程序将工作如下:

Order Service 创建一个 Order,这个订单处于待定状态,然后发布一个OrderCreated事件。

  • Customer Service 接收到这个事件并尝试为这个 Order 扣除信用。然后发布一个 Credit Reserved 事件或者CreditLimitExceeded(超出信用限额)事件。

  • Order Service 接收到 Customer Service 发送的事件并将订单状态更改为已核准或已取消。

7

微服务架构

 1 上下文 

部署基于服务器的企业应用程序,支持各种浏览器和原生移动客户端。应用程序通过执行业务逻辑、访问数据库、与其它系统交换信息并返回响应来处理客户端请求。这个应用程序可能会暴露一个第三方 API。

 2 问题 

一体化应用程序会变得过于庞大和复杂,无法得到有效支持和部署来实现最优的分布式资源利用,例如在云环境中。

 3 方案 

将应用程序构建成服务套件。每个服务都是独立部署和可扩展的,拥有自己的 API 边界。不同的服务可以用不同的编程语言编写,管理它们自己的数据库,由不同的团队开发。

 4 弱点 

系统设计必须能容忍服务失败,需要更多的系统监控。服务编排和事件协作开销比较大。

当然,我们还需要更多钱。

 5 用途 

许多使用场景都可以应用微服务架构,特别是那些涉及大量数据管道的场景。例如,一个微服务系统对关于一个公司的零售店销售的报表系统会比较理想。数据展现过程的每一步都会被一个微服务处理:数据收集、清理、规范化、浓缩、聚合、报告等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

程序员必知的7种软件架构模式 的相关文章

  • WebSphere 中跨 JVM 的会话复制

    我们建立了一个基础设施 其中网络服务器是集群的 而应用程序服务器不是 Web 服务器根据循环策略将请求路由到应用程序服务器 在这种情况下 一个应用程序服务器中可用的会话数据在另一应用程序服务器中不可用 无论如何 是否可以使来自第一个应用程序
  • Spring JDBC 模板。如何获取pl/sql脚本的结果变量

    我正在使用 NamedParameterJdbcTemplate 来运行 pl sql 脚本 但我不知道如何获取out变量的值 id out 提前致谢 String script declare begin if myFunc id in
  • Spring安全+LocaleResolver

    我需要在身份验证成功后更改区域设置 区域设置解析器
  • 检查从 arrayadapter 获取的复选框

    我有标题清单 CheckBox 我想控制默认检查哪一个 所以我试图获得正确的视图并检查它 但由于某种原因它不起作用 知道为什么吗 form checkbox item xml
  • 在 json 中解析尾随字符

    我正在尝试检查 json 是否有效 并且我遇到了奇怪的行为 当我将一些字符附加到可解析的 json 时 jackson 和 gson 都会解析它 并且它们会忽略尾随字符 我想检查 json 是否严格有效 请帮忙 我尝试了几个标志mapper
  • 如何将日期字符串解析为Date? [复制]

    这个问题在这里已经有答案了 如何将下面的日期字符串解析为Date object String target Thu Sep 28 20 29 30 JST 2000 DateFormat df new SimpleDateFormat E
  • Java 表达式树 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有相当于 net的 LINQ 下的表达式树JVM 我想实现一些类似 LINQ 的代码结构Scala
  • Eclipse 无法识别 persistence.xml 的内容

    我在 eclipse 中收到以下错误 persistence xml 文件没有可识别的内容 我的 persistence xml 文件在我的应用程序中工作得很好 但 eclipse 一直给我这个错误 我在移动文件并使用 m2eclipse
  • Java 客户端到服务器未知来源

    我有一个简单的乒乓球游戏 需要通过网络工作 服务器将创建一个带有球和 2 个球棒位置的游戏 当客户端连接到服务器时 服务器将创建一个名为 PongPlayerThread 的新类 它将处理客户端到服务器的输入和输出流 我的服务器工作100
  • Eclipse Oxygen - 该项目未构建,因为其构建路径不完整

    我刚刚安装了 Eclipse Oxygen 并尝试在工作台中打开现有项目 但收到此错误 该项目未构建 因为其构建路径不完整 不能 找到 java lang Object 的类文件 修复构建路径然后尝试 建设这个项目 我尝试右键单击该项目 转
  • 在 libgdx 中渲染 box2d

    我有一个使用 FitViewport 的大小为 800x480 的游戏世界 并且最初使用像素渲染 box2d 实体 固定装置 因此所有物理效果都显得浮动且缓慢 查看文档后 我意识到 box2d 使用度量单位 因此我将 box2d 位置和大小
  • SSLContext 初始化

    我正在看JSSE参考指南 我需要获取一个实例SSLContext为了创建一个SSLEngine 所以我可以使用它Netty以启用安全性 获取实例SSLContext I use SSLContext getInstance 我看到该方法被重
  • 在 java 8 下使用泛型出现类型错误,但在 java 7 下则不然

    我有一段代码可以在 java 7 下编译良好 但不能在 java 8 下编译 这是一个独立的重现示例 我已经采用了显示此问题的真实代码并删除了所有实现 import java util Iterator class ASTNode
  • java.lang.ClassNotFoundException: org.jboss.logging.Logger

    我有一个奇怪的问题 我有一个JMS https en wiktionary org wiki JMS客户端应用程序和MDB https en wikipedia org wiki Enterprise JavaBeans Message d
  • 将 Maven 控制台与 m2eclipse 一起使用

    Maven 新手在这里 有没有办法在 Eclipse 中打开控制台并在 M2Eclipse 插件上执行 Maven 命令 这是一个非常好的插件 但我环顾四周 没有找到我想要的一些功能 谢谢 如果你想运行特定的maven插件 你可以这样做 g
  • Jersey 和 Spring 中的全局异常处理?

    我正在使用 Jersey 和 Spring 3 2 以及 Open CMIS 开发 RESTful Web 服务 我没有使用 Spring 的 MVC 模式 它只是 Spring IOC 和 Jersey SpringServlet 控制器
  • SQlite 获取最近的位置(带有纬度和经度)

    我的 SQLite 数据库中存储有纬度和经度的数据 我想获取距我输入的参数最近的位置 例如我当前的位置 纬度 经度等 我知道这在 MySQL 中是可能的 并且我已经做了相当多的研究 SQLite 需要一个自定义外部函数来实现半正弦公式 计算
  • JavaFX Integer Spinner (IntegerSpinnerValueFactory) 不会将值回绕到最小值

    我创建了一个带有值的整数微调器 min 5 max 15 and initialValue 12 and wrapAround true 一旦旋转器到达max 15 增量期间的值 而不是将值重置为min 5 正如它所说文档 https op
  • 如何从 Sublime Text 编辑器调试 Java 应用程序

    有时我正在对相当大的 Java 应用程序进行简单的修复 但我不想打开 Eclipse 来执行此任务 Eclipse 启动时间很长 并且由于该项目是由大量子项目构建的 而这些子项目无论如何都是由 Maven 构建的 因此需要很长时间才能使用
  • 需要在没有wsdl的情况下调用soap ws

    我是网络服务的新手 这个网络服务是由 siebel 提供的 我需要调用一项网络服务 我的客户向我提供了以下详细信息 这是 SOAP 对于产品 请使用它作为端点 Request

随机推荐

  • Redis哨兵模式(Sentinel)

    哨兵模式 概述 主从切换技术的操作是 当主机宕机后 需要手动把一台从机切换为主机 这就需要人工干预 费事费力 还会造成一段时间内服务不可用 这不是一种推荐的方式 更多时候 我们优先考虑哨兵模式 Redis 从 2 8 开始正式提供了 Sen
  • c++ interview

    数据结构篇 判断单链表是否有环 单链表排序 两个链表合并后仍然有序 网络编程 五层网络架构 tcp和udp的区别 流量控制和拥塞控制 upd通信流程 udp如何实现可靠传输 进程线程篇 多线程如何同步 进程和线程的区别 进程间的通讯方式 并
  • SVM和Softmax分类器比较

    参考 作者 啊噗不是阿婆主 来源 CSDN 原文 https blog csdn net weixin 38278334 article details 83002748 1 SVM和Softmax分类器是最常用的两个分类器 Softmax
  • Centos7.5设置登录欢迎信息-网络系统管理赛项

    由于2022年网络系统管理赛项的修改加之网上的关于这方面的资料以及博客较少 于是我打算写一篇关于Centos7 5设置登录欢迎信息的博客 准备工作 安装Centos7 5并且安装ssh服务的虚拟机一台 1 编写动态脚本 因为单纯修改 etc
  • wget 使用技巧

    wget 是一个命令行的下载工具 对于我们这些 Linux 用户来说 几乎每天都在使用它 下面为大家介绍几个有用的 wget 小技巧 可以让你更加高效而灵活的使用 wget wget r np nd http example com pac
  • 程序编码风格要求

    程序编码风格包括如下要求 使用好程序内部的文档 为了提高程序的可维护性 源代码也需要实现文档化 标识符要见名知意 要有适当的程序注释 注释分为序言性注释和功能性注释 序言性注释通常置于每个程序模块开 头的部分 给出程序的整体说明 功能性注释
  • 【华为OD机试】-2023(B卷)真题【c++,java,python】

    2023B卷 序号 题目分数 时间 1补种未成活胡杨100 2路灯照明问题100 3敏感字段加密100 2023B卷 4阿里巴巴找黄金宝箱 1 100 2023B卷 5喊7的次数重排1002023B卷 6斗地主之顺子1002023B卷 7I
  • 【错误】Description Resource Path Location

    为什么80 的码农都做不了架构师 gt gt gt 警告 Description Resource Path Location Type Projects must be referenced by an EAR or a WAR to u
  • 【opencv】中值滤波代码分析及优化

    最近用opencv做项目 也在研究opencv源码 发现它中值滤波的性能达不到项目的要求 就想办法优化 本文先解析opencv的中值滤波源码 然后针对滤波核尺寸为7和9的情况进行优化 opencv源码分析 opencv4 7 0实现中值滤波
  • inline内联函数总结

    inline只是对编译器的一个申请 不是强制命令 优点 1 比宏的坑少 而且减少函数调用所招致的额外开销 缺点 1 有可能使目标代码增加 减少了高速缓存的命中率 如果编译器针对 函数本身 所产出的码可能比针对 函数调用 所产出的码更小 果真
  • cesium for ue->CesiumGeospatial

    共32个文件 4257行代码 含注释 截至2022年11月26日 剩余23个文件 3162行代码 截至2022年11月27日 剩余19个文件 2671行代码 截至2022年11月28日 剩余17个文件 2438行代码 截至2022年11月2
  • react-router源码

    1 Router js Router js模块用于监听hashChange popState事件 通过当前页面url更新Router组件的state state形式为 location routes params components 其中
  • SQLi-LABS Less-18到Less-22 头部注入

    Less 18题目 先抓包 由它题目可以知道 这是头部注入 其实我也并不知道头部注入这个姿势 刚好做这道题让我了解一下 在百度过后 头部注入的话已经不能在用户名以及密码那输入SQL语句了 只能通过抓包改包看回显了 这里使用你在Less 17
  • BOSE在上海发布6款音频新品;轩尼诗全球首家概念酒吧在上海开幕

    今日看点 2020 BOSE音频新品发布会在上海举行 此次发布会总共发布了6款产品 包括Bose 消噪耳塞 Bose无线耳塞 Bose 智能音频眼镜 猫眼款和运动款 Bose 遮噪睡眠耳塞 II QC 35 II GAMING HEADSE
  • Shell基础:批量运行程序

    创建可执行程序 文件名 hello c include
  • 将eclipse项目导入idea

    首相我们需要明白idea的两个概念 在idea中project相当于eclipse的workspace 在idea中project相当于eclipse的project 所有首先我们需要新建一个在idea中创建一个project 点击菜单fi
  • 标签
  • 引起的缩进问题 list-style: none outside none;
  • 一般网站css都有相应的初始化部分 最近遇到一个棘手问题 li 标签里面的东西 在firefox下正常 而在ie6全部被缩进 而初始化的部分css也有 list style none 并且这个li没有相应的id或者class 那么是被什么控
  • Python判断指定日期是不是中国工作日/节假日

    判断一个日期是否为工作日 节假日 有一个现成的库函数 chinesecalendar chinesecalendar PyPI 1 安装与升级 1 1 安装 pip3 install chinesecalendar 1 2 升级 pip i
  • 11.全连接卷积神经网络 FCN

    视频 48 全连接卷积神经网络 FCN 动手学深度学习v2 哔哩哔哩 bilibili 书籍 13 11 全卷积网络 动手学深度学习 2 0 0 beta0 documentation d2l ai PPT part 2 16 pdf d2
  • 程序员必知的7种软件架构模式

    架构模式是对给定上下文的软件架构中常见问题的一种通用的可复用的解决方案 一种模式就是特定上下文的问题的一种解决方案 然而 很多开发者至今还对各种软件架构模式之间的差别搞不清 甚至对其所知甚少 大体上 主要有下面这7种架构模式 分层架构 多层