7.3 - 软件架构风格
软件体系结构设计的一个重要目的就是架构复用, 也就是不同的软件系统使用同一架构。复用的好处是节约时间、提高效率、减少开发风险。
|-------------------|--------------|--------------|--------------|-------------|------------|
| 大类名称 | 子类名称 | 特点 | 应用场景 | 优点 | 缺点 |
| 调用/返回风格 | 主程序/子程序风格 | 单线程、过程调用、层次性 | 传统过程式编程(C) | 简单易理解、分解复杂度 | 调用链复杂 |
| 调用/返回风格 | 面向对象风格 | 数据抽象、封装、继承 | 面向对象编程(Java) | 高重用性、低耦合 | 性能开销大 |
| 调用/返回风格 | 层次型风格 | 层次结构、服务/客户模式 | 网络协议、操作系统 | 层次清晰、易扩展 | 层耦合较强 |
| 调用/返回风格 | 客户端/服务器风格 | 前端/后端分离、资源共享 | Web应用、分布式系统 | 职责明确、易扩展 | 服务器压力大 |
| 数据流风格 | 批处理风格 | 批量处理、步骤执行 | 数据清洗、批处理任务 | 执行效率高 | 实时性差 |
| 数据流风格 | 管道-过滤器风格 | 数据流、模块独立处理 | 编译器、信号处理 | 模块化、并行处理 | 依赖关系复杂 |
| 虚拟机风格 | 解释器风格 | 解析代码、虚拟运行环境 | 解释器、虚拟机 | 灵活性高 | 执行效率低 |
| 虚拟机风格 | 规则系统风格 | 规则集、自动处理 | 专家系统、决策系统 | 规则易维护、易扩展 | 规则冲突复杂 |
| 以数据为中心的风格 | 仓库风格 | 中央数据存储、构件操作 | 数据库系统、版本控制 | 数据集中、易管理 | 性能瓶颈、单点故障 |
| 以数据为中心的风格 | 黑板风格 | 知识共享、黑板求解 | 模式识别、语音识别 | 适合复杂问题 | 设计复杂 |
| 独立构件风格 | 进程通信风格 | 独立进程、消息传递 | 分布式系统、微服务架构 | 低耦合、分布式部署 | 消息开销大 |
| 独立构件风格 | 事件系统风格 | 事件驱动、隐式调用 | GUI、监控系统 | 模块解耦、异步处理 | 调试复杂 |
1、数据流风格
数据流体系结构:主要关注数据的流动和处理。
传统的冯·诺依曼体系结构:指令的执行顺序。
核心概念
-
无程序计数器:指令的执行是根据输入数据来决定的,而不是依赖于预定的顺序。
-
数据驱动:指令只有在其所需的输入数据可用时才会被执行。
-
不确定性:执行的顺序会根据输入的状态和数据流的变化而变化。
主要风格
数据流体系结构主要有以下两种常见风格:
1-1、批处理风格:
概念:等数据收集一批次后,整个批次同时被送入处理单元进行计算。
特点:需要等待数据集成为一批,集中处理所以执行效率高,一般离线处理(有延时)
场景:适合于大规模数据的离线处理,例如数据挖掘、统计分析等。
1-2、管道-过滤器风格:
概念:将处理过程分解为多个独立的处理单元(过滤器),上一个过滤器的输出是下一个的输入。
特点:独立性------各个过滤器单独维护,并行处理------各个过滤器同时工作。过滤器灵活组合、单个过滤器可在多个系统中复用,但若某个过滤器慢,则会降低整体系统效率。
场景:强调模块化和实时处理,音频和视频流处理、编译器设计等。
2、调用、返回风格
通过采用调用和返回机制,将复杂的系统划分为多个子系统,降低复杂性、增加可修改性。
2-1 主程序/子程序风格
主程序/子程序风格采用单线程控制,将问题分解为多个处理步骤,其中构件包括主程序和子程序。子程序通常可以封装成模块,方便复用和管理。大多数传统编程语言(如 C、Pascal)采用这种风格进行程序设计,有以下几个特点:
- 过程调用:通过过程调用作为构件之间的交互机制,这样可以简化系统的控制流。
- 层次关系:程序的正确性依赖于他所调用的子程序结果。
- 模块化:通过将功能划分为多个子程序,可以实现模块化设计,提高可维护性。
2-2 面向对象体系结构风格
面向对象体系结构风格建立在++数据抽象和面向对象编程++的基础上,被目前应用软件开发广泛使用,有以下几个特点:
- 数据封装:数据的表示和操作被封装在对象中,外部只能通过对象提供的接口访问数据。
- 继承和多态:支持类的继承与多态性,使得系统更具灵活性和可扩展性。
- 模块化:通过对象的组合和重用,可以提高系统的可维护性和可扩展性。
2-3 层次型体系结构风格
层次型体系结构将系统分为多个层次,每一层为上层提供服务,并作为下层的客户。典型的例子有:网络协议栈(如 OSI 模型)和操作系统架构。层次型体系结构风格有以下几个特点:
- 分层结构 :每一层只与相邻的上下两层进行交互,降低层与层之间的耦合度。
- 接口标准化:每层提供相同的接口,允许下层用不同的方法实现,增强了软件重用性。
- 层间协议:通过定义层间的交互协议,来管理层之间的关系。
2-4客户端/服务器体系结构风格
客户端/服务器(C/S)体系结构是一种基于资源不对等的分布式架构 ,通常用于实现数据共享 和功能分配,例如Web 应用程序。他有以下几个特点:
- 两层结构:基本的 C/S 体系结构包括数据库服务器、客户应用程序和网络。服务器负责数据管理,而客户端负责与用户交互。
- 三层结构 :在三层 C/S 结构中,增加了应用服务器,系统分为表示层(用户界面)、功能层(业务逻辑)和数据层(数据库管理)。
- 资源共享:客户端和服务器之间通过网络进行数据交换,允许多个客户端共享服务器的资源。
两层结构 三层结构
3、以数据为中心的体系结构风格
3-1. 仓库体系结构风格
仓库体系结构风格将数据存储在一个中心位置(即仓库),并通过一组独立的构件对这些数据进行操作。适用于需要集中管理和维护大量数据的系统,例如数据库管理系统 、**企业数据仓库,**有以下几个特点:
- 中央数据仓库:所有数据存储在中央仓库中,仓库维护数据的当前状态。
- 独立构件:系统中有多个独立构件,它们通过访问中央仓库来进行数据操作。
- 解耦合:构件之间的相互作用是通过仓库进行的,从而降低了构件之间的耦合度。
3-2. 黑板体系结构风格
适用于解决复杂的非结构化问题。它通过一个共享的黑板(即共享数据存储)来组织和求解问题,能够综合运用多种知识源和推理机制。应用举例有语音识别、图像处理。其特点有:
- 共享黑板:所有信息存储在一个黑板上,代表问题的部分解。
- 知识源:系统包含多个独立的知识模块(知识源),每个知识源可以处理黑板上的信息并进行推理,生成新的信息。
- 非线性求解:允许不同知识源根据需要独立工作。
4、虚拟机风格
创建一个人为构建的运行环境,允许解析和执行自定义语言,从而提高架构的灵活性。
4-1 解释器体系结构风格
解释器体系结构风格的核心在于实现一个虚拟机 ,该虚拟机能够仿真硬件的执行过程,并解释运行自定义编程语言的代码。适合需要动态执行代码的场景,应用例如如 Python、Ruby 的解释器。
通常由几个主要组件构成:
主要组件
- 解释引擎:负责解释和执行代码。
- 代码存储区:存储被解释的程序代码。
- 当前状态数据结构:记录解释引擎的当前工作状态。
- 进度数据结构:跟踪源代码执行的进度。
优点:跨平台、支持快速开发代码。缺点:性能低。
4-2 规则系统体系结构风格
基于规则的系统通过一组规则进行知识表示和推理,适合处理复杂推理和知识管理的应用,应用有专家系统、自动决策系统,其组成由:
- 规则集:存储用于推理的所有规则。
- 规则解释器:负责选择和执行合适的规则。
- 规则/数据选择器:根据当前状态选择适用的规则和数据。
- 工作内存:存储当前的事实集和触发的数据。
知识库中存放着规则集、事实集,能够给予当前数据动态选择要执行的规则,规则是可以修改的。
优点:有强大的表达能力,通过分离代码和规则使系统可维护性高。缺点:复杂、性能。
5、独立构件风格
强调系统中的构件是相对独立的个体,他们之间间接通信,从而降低耦合度并提升系统的灵活性。
5-1. 进程通信体系结构风格
系统的构件通常是独立的进程,这些进程通过消息传递来进行通信。进程通信通过明确的消息传递方式实现构件之间的交互,应用实例有分布式系统、微服务架构。其特点有:
- 消息传递:构件之间通过发送和接收消息进行交互。消息可以是点对点的,也可以是广播的。
- 连接方式:消息传递可以采用同步或异步的方式,或使用远程过程调用(RPC)。
- 降低耦合度:由于构件之间不直接调用,系统的耦合度大大降低,增强了灵活性和可维护性。
5-2. 事件系统体系结构风格
构件不直接调用其他构件,而是通过触发或广播事件来通知其他构件。事件系统通过事件的发布和处理实现了更高层次的解耦合,应用实例有图形化界面,即用户点击按钮后触发处理。其主要特点有:
- 事件驱动 :构件通过发布事件而非直接调用其他构件的过程,增强了模块之间的独立性。
- 注册机制 :系统中的构件可以注册为特定事件的处理程序。
- 解耦合:事件的触发者不需要知道哪些构件会受到影响。