程序员必知的7种软件架构模式
作者:Trung Anh Dang
策划:万佳
架构模式是对给定上下文的软件架构中常见问题的一种通用的可复用的解决方案。
一种模式就是特定上下文的问题的一种解决方案。
然而,很多开发者至今还对各种软件架构模式之间的差别搞不清,甚至对其所知甚少。
大体上,主要有下面这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 用途
许多使用场景都可以应用微服务架构,特别是那些涉及大量数据管道的场景。例如,一个微服务系统对关于一个公司的零售店销售的报表系统会比较理想。数据展现过程的每一步都会被一个微服务处理:数据收集、清理、规范化、浓缩、聚合、报告等。
特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:长按订阅更多精彩▼如有收获,点个在看,诚挚感谢
程序员必知的7种软件架构模式相关推荐
- 程序员必知的几种软件架构模式
程序员必知的几种软件架构模式 前序 分层架构模式 多层模式 管道 - 过滤器架构 客户端 - 服务器架构 模型 - 视图 - 控制器架构(MVC) 事件驱动架构 微服务架构 前序 架构模式是对给定上下 ...
- 程序员必知的 4 种命名方式
文章目录 1.camel case (驼峰式) 2.snake case (蛇形式) 3.kebab case (烤串式) 4.匈牙利命名法 5.小结 参考文献 编码时,命名无处不在. 比如我们需要对 ...
- java 字符串转骆驼命名_程序员必知的Java基础:5条命名规范和8种数据类型归纳...
原标题:程序员必知的Java基础:5条命名规范和8种数据类型归纳 一.Java命名规范 任何一种语言都有一套针对于语言自身的命名的规范,java也不例外.接下来,我就列举一下java对命名的规范. 下 ...
- 程序员必知8大排序3大查找(三)
前两篇 <程序员必知8大排序3大查找(一)> <程序员必知8大排序3大查找(二)> 三种查找算法:顺序查找,二分法查找(折半查找),分块查找,散列表(以后谈) 一.顺序查找的基 ...
- 程序员必知必会之maillist篇
程序员必知必会之maillist篇 本文最初由恋花蝶发表于http://blog.csdn.net/lanphaday,可以随意转载,但未经同意不得增删修改,转载应保留本声明,否则追究责 ...
- 程序员必知必会之blog篇
程序员必知必会之blog篇 网易广州 赖勇浩(http://blog.csdn.net/lanphaday) 本文最初发表于恋花蝶的博客(http://blog.csdn.net/lanp ...
- 专业程序员必知必会技巧:驯服复杂代码
感悟:虽然不想做一个程序员,但还是自做这些事情!艺术家首先是工匠!多美妙的哲理,可是路途漫长而很多人选择了放弃,我也想放弃了.更重要的是,如果希望是一个艺术家,首先是一个NB的工程师. 原文链接:ht ...
- 专业程序员必知必会的技巧:驯服复杂代码
你从入职第一天起就要应对复杂代码. 若是还未遇到过无法理解的程序,那说明你编程的年头还不够长.在行业里,要不了多久你就会碰到让人发懵的混乱代码:巨兽.面条工厂.来自地狱的遗留系统.我曾接手过一个程序, ...
- 程序员必知8大排序3大查找(一)
每天都在叫嚣自己会什么技术,什么框架,可否意识到你每天都在被这些新名词.新技术所迷惑,.NET.XML等等技术固然诱人,可是如果自己的基础不扎实,就像是在云里雾里行走一样,只能看到眼前,不能看到更远的 ...
最新文章
- CSS选择器和参考手册
- OpenFlow Switch — 1.3 规范
- MySQL第9天:MySQL索引优化分析之join查询
- oracle 根据分隔符提取,oracle根据分隔符获取字符串
- 生产者跟消费者问题(C++实现)
- 恒驰机器人_恒大汽车基地:2545台机器人为恒驰“效力”
- 大型web系统数据缓存设计-l转载
- 为什么我们做分布式要用 Redis ?
- 解决pip安装时速度慢的问题 镜像源(pip install -i [镜像源地址] [包名])
- Reat学习01——初步接触与安装
- Python模拟Linux的Crontab, 写个任务计划需求
- linux网络编程之用epoll实现io复用(基于tcp)
- iOS-贝塞尔曲线之自定义饼图
- 使用动态优先权的进程调度算法的模拟_我爱OS第12讲:系统调度
- python基于给定时间戳生成 未来/过去 前进/倒退 n个小时的时间戳
- JAVA商城系统开发 VS PHP商城系统开发
- [渝粤教育] 重庆工程职业技术学院 数控机床编程与操作 参考 资料
- 使用Tesseract-OCR识别图片中的文字并生成双层PDF
- crc原理及c代码实现
- 矩阵求逆的几种方法总结(C++)
热门文章
- js之浅拷贝和深拷贝
- oracle修改c root,从新发现Oracle太美之root.sh
- 关于学习Python的一点学习总结(16->popitem()->sedefault()->update()->values())
- 关于学习Python的一点学习总结(10->设置字符串格式)
- 求和(dfs序+线段树)
- trie树上值域化建主席树 查询异或平移最小值 ---- P3293 [SCOI2016]美味
- Codeforces1600数学day5[找规律CodeForces - 1059C,贪心数学A - Banh-mi CodeForces - 1062C ]
- sock 文件方式控制宿主机_nginx与php-fpm通信的两种方式
- php递归内存,PHP递归的三种常用方式
- P2574 XOR的艺术(线段树)