[Arch] 04. Software Architectural Patterns
让我们一起 回忆:
原则 | 基本认识 |
S | 应该仅有一个引起它变化的原因 |
O | 在不被修改的前提下被扩展 |
L | 尽量从抽象类继承 |
I | 应该依赖于抽象 |
D | 倾向瘦接口 |
让我们开始 新课:
[Design Patterns] 03. Practice UML in project 的 "文档列表" 其实就是”过程模式“的一种。
“设计模式”会在将来单独讲解
这里主要学习“体系结构模式”和“分析模式”。
体系架构模式
Ref: 10种常见的软件架构模式
Ref: 软件架构模式 (30页的书)
若干重要模式
黑板模式
这种模式对于没有确定解决方案策略的问题是有用的。黑板模式由3个主要组成部分组成。
-
- 黑板——包含来自解决方案空间的对象的结构化全局内存
- 知识源——专门的模块和它们自己的表示
- 控制组件——选择、配置和执行模块
所有的组件都可以访问黑板。
组件可以生成添加到黑板上的新数据对象。
组件在黑板上查找特定类型的数据,并通过与现有知识源的模式匹配来查找这些数据。
使用场景:
-
- 语音识别
- 车辆识别和跟踪
- 蛋白质结构识别
- 声纳信号的解释
利用数据库
利用发布—订阅模式
MVC模式(模型-视图-控制器)
Ref: Android Module] 03 - Software Design and Architecture
一个小的项目且无需频繁修改需求就不用MVC框架来设计了,那样反而觉得代码过度设计,代码臃肿。
一般在大的项目中,且业务逻辑处理复杂,页面显示比较多,需要模块化设计的项目使用MVC就有足够的优势了。
【是不是还有更大的项目,那该如何?】
在MVC模式中我们发现,其实控制器Activity主要是起到解耦作用,将View视图和Model模型分离。
-
- View 视图和Activity 控制器并不是完全分离的
- 虽然Activity起到交互作用,但是找Activity中有很多关于视图UI的显示代码
【需要清除掉activity中的视图代码残渣,但还是先把业务逻辑分离开来才是要紧之事】
MVP模式(模型-视图-控制器)
Ref: Android Module] 03 - Software Design and Architecture
链接已讲。把业务逻辑从Activity中挪出来,挪到Presenter中去,让Activity回归View的角色,从此Presenter专注于业务,View专注于显示。
View恳求Presenter帮忙问问Model是否能给点数据。
Model通过实现回调函数对外提供了一个接口给Presenter。
简单的讲:View调用Presenter的函数,该函数内部调用Model的一个回调函数实现的接口。
[Android Module] 08 - MVP by Mosby
其他
* MVVM - [Android Module] 06 - DataBinding and MVVM。
* 起源于React的Flux框架。
另外几种模式
From: 10种常见的软件架构模式
分层模式
一般信息系统中最常见的是如下所列的4层。
-
- 表示层(也称为UI层)
- 应用层(也称为服务层)
- 业务逻辑层(也称为领域层)
- 数据访问层(也称为持久化层)
Jeff:其实就是传统模型。
客户端-服务器模式
典型场景:邮件服务器和浏览器的关系
主从设备模式
主设备组件在相同的从设备组件中分配工作,并计算最终结果,这些结果是由从设备返回的结果。
管道-过滤器模式
管道-过滤器模式的体系结构是面向数据流的软件体系结构。它最典型的应用是在编译系统。一个普通的编译系统包括词法分析器,语法分析器,语义分析与中间代码生成器,优化器,目标代码生成器等一系列对源程序进行处理的过程。
Jeff: 有点生僻
代理模式
此模式用于构造具有解耦组件的分布式系统。
使用场景:消息代理软件,如Apache ActiveMQ,Apache Kafka,RabbitMQ和JBoss Messaging
点对点模式
在这种模式中,单个组件被称为对等点。对等点可以作为客户端,从其他对等点请求服务,作为服务器,为其他对等点提供服务。对等点可以充当客户端或服务器或两者的角色,并且可以随时间动态地更改其角色。
使用场景:
-
- 像Gnutella和G2这样的文件共享网络
- 多媒体协议,如P2PTV和PDTP
- 像Spotify这样的专有多媒体应用程序
Jeff: 有点生僻
事件总线模式
类似于消息广播。
模型-视图-控制器模式
已阅。
黑板模式
已阅。
解释器模式
这个模式用于设计一个解释用专用语言编写的程序的组件。它主要指定如何评估程序的行数,即以特定的语言编写的句子或表达式。其基本思想是为每种语言的符号都有一个分类。
使用场景:
-
- 数据库查询语言,比如SQL
- 用于描述通信协议的语言
每种体系架构模式的优缺点
名称 | 优点 | 缺点 |
---|---|---|
分层模式 | 一个较低的层可以被不同的层所使用。层使标准化更容易,因为我们可以清楚地定义级别。可以在层内进行更改,而不会影响其他层。 | 不是普遍适用的。在某些情况下,某些层可能会被跳过。 |
客户端-服务器模式 | 很好地建立一组服务,用户可以请求他们的服务。 | 请求通常在服务器上的单独线程中处理。由于不同的客户端具有不同的表示,进程间通信会导致额外开销。 |
主从设备模式 | 准确性——将服务的执行委托给不同的从设备,具有不同的实现。 | 从设备是孤立的:没有共享的状态。主-从通信中的延迟可能是一个问题,例如在实时系统中。这种模式只能应用于可以分解的问题。 |
管道-过滤器模式 | 展示并发处理。当输入和输出由流组成时,过滤器在接收数据时开始计算。轻松添加过滤器,系统可以轻松扩展。过滤器可重复使用。 可以通过重新组合一组给定的过滤器来构建不同的管道。 | 效率受到最慢的过滤过程的限制。从一个过滤器移动到另一个过滤器时的数据转换开销。 |
代理模式 | 允许动态更改、添加、删除和重新定位对象,这使开发人员的发布变得透明。 | 要求对服务描述进行标准化。 |
点对点模式 | 支持分散式计算。对任何给定节点的故障处理具有强大的健壮性。在资源和计算能力方面具有很高的可扩展性。 | 服务质量没有保证,因为节点是自愿合作的。安全是很难得到保证的。性能取决于节点的数量。 |
事件总线模式 | 新的发布者、订阅者和连接可以很容易地添加。对高度分布式的应用程序有效。 | 可伸缩性可能是一个问题,因为所有消息都是通过同一事件总线进行的。 |
模型-视图-控制器模式 | 可以轻松地拥有同一个模型的多个视图,这些视图可以在运行时连接和断开。 | 增加复杂性。可能导致许多不必要的用户操作更新。 |
黑板模式 | 很容易添加新的应用程序。扩展数据空间的结构很简单。 | 修改数据空间的结构非常困难,因为所有应用程序都受到了影响。可能需要同步和访问控制。 |
解释器模式 | 高度动态的行为是可行的。对终端用户编程性提供好处。提高灵活性,因为替换一个解释程序很容易。 | 由于解释语言通常比编译后的语言慢,因此性能可能是一个问题。 |
新潮模式
微内核架构
微服务架构
微服务常常伴随的REST API:[Node.js] 08 - Web Server and REST API
问题 [1] SOA和微服务架构的区别?
如果一句话来谈SOA和微服务的区别,即微服务不再强调传统SOA架构里面比较重的ESB企业服务总线,同时SOA的思想进入到单个业务系统内部实现真正的组件化。
其次,从实现方式上,两者都是中立性,语言无关,协议跨平台,相比SOA,微服务框架将能够带来更大的敏捷性,并为你构建应用提供更轻量级、更高效率的开发。而SOA更适合大型企业中的业务过程编排、应用集成。另外还有微服务甚至是去ESB、去中心化、分布式的,而SOA还是以ESB为核心,大量的WS标准实现。
再次,从服务粒度上,既然是微,必然微服务更倡导服务的细粒度,重用组合,甚至是每个操作(或方法)都是独立开发的服务,足够小到不能再进行拆分。而SOA没有这么极致的要求,只需要接口契约的规范化,内部实现可以更粗粒度,微服务更多为了可扩充性、负载均衡以及提高吞吐量而去分解应用,但同时也引发了打破数据模型以及维护一致性的问题。
最后,从部署方式上,这个是最大的不同,对比Monolithic(有人翻译为单体)的Java EE部署架构,通过展现层打包WARs,业务层划分到JARs最后部署为EAR一个大包,而微服务则打开了这个黑盒子,把应用拆分成为一个一个的单个服务,应用Docker技术,不依赖任何服务器和数据模型,是一个 全栈应用,可以通过自动化方式独立部署,每个服务运行在自己的进程中,通过轻量的通讯机制联系,经常是基于HTTP资源API,这些服务基于业务能力构建,能实现集中化管理(因为服务太多啦,不集中管理就无法DevOps啦)。
问题 [2] 我所理解的SOA和微服务
微服务其实就是随着互联网的发展,复杂的平台、业务的出现,导致SOA架构向更细粒度、更通过化程度发展,就成了所谓的微服务了。以这种说法做为根据,我觉得SOA与微服务的区别在于如下几个方面:
- 微服务相比于SOA更加精细,微服务更多的以独立的进程的方式存在,互相之间并无影响;
- 微服务提供的接口方式更加通用化,例如HTTP RESTful方式,各种终端都可以调用,无关语言、平台限制;
- 微服务更倾向于分布式去中心化的部署方式,在互联网业务场景下更适合;
问题 [3] 谁能用通俗的语言解释一下什么是 RPC 框架?
RPC就是要像调用本地的函数一样去调远程函数。
Netty框架不局限于RPC,更多的是作为一种网络协议的实现框架,比如HTTP,由于RPC需要高效的网络通信,就可能选择以Netty作为基础。
除了网络通信,RPC还需要有比较高效的序列化框架,以及一种寻址方式。
如果是带会话(状态)的RPC调用,还需要有会话和状态保持的功能。
参考学习:Dubbo的网站架构发展图
- 单一应用架构
- 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
- 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
- 垂直应用架构
- 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
- 此时,用于加速前端页面开发的 Web框架(MVC) 是关键。
- 分布式服务架构
- 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
- 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
- 流动计算架构
- 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
- 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。
平台随着业务的发展从 All in One 环境就可以满足业务需求(以Java来说,可能只是一两个war包就解决了);发展到需要拆分多个应用,并且采用MVC的方式分离前后端,加快开发效率;
在发展到服务越来越多,不得不将一些核心或共用的服务拆分出来,其实发展到此阶段,如果服务拆分的足够精细,并且独立运行,我觉得就可以将之理解为一个微服务了。
End.