🗓️ 2025-12-04 🎖️ 软件架构之道 🗂️ 读书笔记, 软件工程 🏷️ #设计模式

《面向模式的软件架构 卷1:模式系统》读书笔记

概览

本书不仅仅是模式的目录,更是一套模式系统。模式(Pattern)是记录专家经验、解决特定设计问题的规范化方法。学习这些模式,能让我跳过多年的试错过程,直接站在巨人的肩膀上,构建出具备高可修改性、可重用性和可靠性的软件系统。本书提供的架构模式、设计模式和成例,分别从宏观结构、局部设计和语言细节三个层面提供了指导。


第1章 模式(Patterns)

本章系统地介绍了模式的概念和描述模式的原则。

概念 总结与理解
模式是什么 模式是对在特定情境下,某个反复出现的问题的解决方案的描述,它详细说明了如何解决问题、为什么解决以及该方案的优缺点。模式不是最终的代码,而是抽象的设计智慧。
模式的分类 模式分为三个抽象层次:架构模式 (Architectural Patterns)(最高层,提供系统骨架),设计模式 (Design Patterns)(中层,解决常见设计问题),成例 (Idioms)(最低层,语言特定的模式)。
模式之间的关系 模式并非孤立,它们相互关联、协作。一个架构模式可以由多个设计模式实现,一个设计模式的实现可能依赖于特定的成例。理解这种关系是构建模式系统的关键。

第2章 架构模式(Architectural Patterns)

架构模式是最高层的模式,旨在提供系统架构的整体骨架,决定了整个系统的组织结构和高层特性。

2.2 从混乱到有序

2.2.1 Layers 模式(分层)

总结项 内容
模式总结/定义 一种将应用程序划分为多组子任务的结构化方式,其中每组子任务都位于特定抽象层。
解决问题 管理复杂的系统结构,实现关注点分离,提升系统的可修改性、可维护性和可重用性。
模式架构 系统被组织成一组抽象层级(Layer J),第J+1层只使用第J层的服务。这种单向依赖关系保证了层级的清晰性。
优缺点总结 优点: 职责分离清晰,易于替换和修改特定层的实现,支持增量开发。 缺点: 严格分层可能导致不必要的层间通信开销(性能损耗);难以确定合适的抽象层级。
可能的应用方向 几乎所有大型软件系统,尤其是网络协议栈(如TCP/IP)、操作系统和企业级应用的三层/多层架构。

2.2.2 Pipes and Filters 模式(管道与过滤器)

总结项 内容
模式总结/定义 一种适用于处理数据流的系统结构,将任务分解为一系列独立、顺序处理数据的单元。
解决问题 应对数据处理流程中对灵活性、可重用性、可维护性和易于理解的要求。
模式架构 过滤器(Filters)管道(Pipes) 组成。过滤器是独立的、处理输入流并产生输出流的组件。管道负责连接过滤器,传输数据流。
优缺点总结 优点: 组件高度解耦,可重用性极强;易于通过添加、替换或重新排列过滤器来修改处理流程。 缺点: 仅限于数据流处理系统;数据格式约定是挑战;难以处理交互式或流式处理不适用的情况。
可能的应用方向 编译器前端(词法分析、语法分析),ETL(抽取、转换、加载)工具,UNIX Shell命令链。

2.2.3 Blackboard 模式(黑板)

总结项 内容
模式总结/定义 一种用于解决没有明确解决策略的复杂问题的模式,多个专业子系统通过集思广益,逐步逼近可能的部分解。
解决问题 解决问题领域知识分散、且缺乏确定性算法的复杂问题。
模式架构 包含三个主要组件:黑板 (Blackboard)(集中存储问题、部分解和推测),知识源 (Knowledge Sources)(专用子系统,对黑板状态变化做出反应),控制组件 (Control)(驱动推理过程,决定知识源的执行顺序)。
优缺点总结 优点: 适合启发式问题求解和实验性系统;高度模块化,易于添加新的知识源。 缺点: 黑板可能成为性能瓶颈;知识源之间的协作逻辑(控制组件)复杂难设计。
可能的应用方向 语音识别,模式识别,AI专家系统,机器人控制。

2.3 分布式系统

Broker 模式(中间人)

总结项 内容
模式总结/定义 用于设计包含通过远程服务调用交互的组件的分布式软件系统。
解决问题 应对分布式系统中客户端和服务端的解耦、位置透明性以及通信协议的隐藏。
模式架构 中间人 (Broker) 负责协调组件间的通信。主要组件包括客户端、服务器、中间人、客户端代理和服务器端代理。中间人利用名称服务实现位置透明。
优缺点总结 优点: 客户端无需知道服务的位置,实现了高度的位置透明性;解耦客户端和服务端,提高了系统的可扩展性。 缺点: 引入了额外的中间层,增加了通信延迟;中间人本身可能成为性能瓶颈或单点故障。
可能的应用方向 CORBA/COM等分布式对象系统,面向服务的架构 (SOA),微服务架构中的服务注册与发现。

2.4 交互式系统

2.4.1 Model-View-Controller 模式(MVC)

总结项 内容
模式总结/定义 将交互式应用程序划分为三个组件:核心功能、表示和控制。
解决问题 将用户界面(表示和控制)与业务逻辑(核心功能)分离,提高系统的可修改性和可重用性。
模式架构 模型 (Model) (封装业务数据和逻辑);视图 (View) (展示数据);控制器 (Controller) (处理用户输入)。视图通过Publisher-Subscriber模式观察模型变化,确保同步。
优缺点总结 优点: 职责分离清晰,易于修改和扩展用户界面;支持同一模型拥有多个视图。 缺点: 增加了系统的复杂性(引入了许多类);视图和控制器有时耦合较紧密。
可能的应用方向 桌面GUI应用,Web应用程序框架(许多Web MVC框架是变体)。

2.4.2 Presentation-Abstraction-Control 模式(PAC)

总结项 内容
模式总结/定义 定义了一种适用于交互式软件系统的结构,由相互协作的智能体(Agents) 组成的层次结构。
解决问题 解决MVC模式在大型、复杂、需要多层次控制和协调的交互式系统中的扩展性问题。
模式架构 每个智能体都包含:表示 (Presentation)抽象 (Abstraction) (功能核心) 和 控制 (Control) (通信和协调)。控制组件是智能体通信的枢纽。
优缺点总结 优点: 层次化和模块化程度更高,更适合复杂的系统;更好的关注点分离。 缺点: 比MVC更复杂,理解和实现难度更高;智能体间的通信和协调逻辑复杂。
可能的应用方向 复杂的图形用户界面,具有多层交互和协调的系统。

2.5 可适应系统

2.5.1 Microkernel 模式(微核)

总结项 内容
模式总结/定义 适用于必须能够适应需求不断变化的系统,将最基本的功能核心与扩展功能分离。
解决问题 应对核心系统需要高适应性、可扩展性,并支持多种定制化需求的问题。
模式架构 微核 (Microkernel) 位于最底层,只提供最小的必要核心功能。扩展功能则作为外部服务器 (External Servers) 运行,通过微核提供的机制进行协作。微核充当插座。
优缺点总结 优点: 扩展性高,适应性强;系统故障隔离性好(服务器间的独立性);易于移植。 缺点: 由于功能大部分在微核外,需要大量的进程间通信(IPC),可能造成性能损耗。
可能的应用方向 操作系统(如Linux、Windows NT的早期设计),产品线架构,插件式应用框架。

2.5.2 Reflection 模式(反射)

总结项 内容
模式总结/定义 提供了一种动态修改软件系统的结构和行为的机制。
解决问题 系统需要极高的运行时适应性和可配置性,允许系统在运行时检查并修改自身的结构和行为。
模式架构 基层 (Base Level)元层 (Meta Level) 组成。基层包含应用逻辑,元层包含关于基层的元信息(如类型、函数调用机制),元层提供了检查和修改基层的接口。
优缺点总结 优点: 极高的动态适应性;能够实现高级、复杂的运行时行为(如动态配置、AOP)。 缺点: 极大地增加了系统的复杂性;运行时修改可能引入难以预料的错误;性能开销大。
可能的应用方向 动态语言运行时,面向方面的编程(AOP),软件配置管理系统。

第3章 设计模式(Design Patterns)

设计模式在架构模式的框架下,解决了软件系统局部结构和协作方面的常见问题。

模式名称 解决了什么问题 模式架构总结 优缺点/应用方向
Whole-Part (3.2) 将组件聚合成一个语义整体。 定义了整体 (Whole) 组件如何管理一个或多个部分 (Part) 组件的生命周期和关系。 应用方向: 复合文档、UI控件组。 优点: 封装了复杂性,明确了聚合关系。
Master-Slave (3.3) 提高计算的并行性、准确度和容错性。 主组件 (Master) 分配工作给多个相同的从组件 (Slave),并汇总从组件的结果。 应用方向: 并行计算、容错系统、分布式计算。 优点: 提高性能和系统可靠性。
Proxy (3.4) 控制对对象的访问,提供代表而非组件本身通信。 代理 (Proxy) 对象与实际主题 (Real Subject) 实现相同接口,客户端通过代理访问实际主题。 应用方向: 远程代理(RPC),虚拟代理(延迟加载),保护代理(访问控制)。 优点: 提高效率,简化访问,保护实际对象。
Command Processor (3.5.1) 将服务的请求和执行分离,支持额外的服务,如撤销/重做。 命令处理器 (Command Processor) 管理封装请求的命令对象 (Command Object) 列表。 应用方向: 编辑器中的操作历史,事务管理。 优点: 支持撤销/重做功能,请求发送者与执行者解耦。
View Handler (3.5.2) 管理软件系统提供的所有视图,协调视图间依赖关系和更新。 视图处理器 (View Handler) 集中管理视图 (Views) 的创建、销毁和协调更新。 应用方向: 多窗口/多面板GUI应用,IDE。 优点: 简化了视图管理和协调,保证一致性。
Forwarder-Receiver (3.6.1) 实现透明的进程间通信(IPC)。 通过引入转发者 (Forwarder)接收者 (Receiver) 将对等体与底层通信机制解耦。 应用方向: 分布式系统中的对等通信。 优点: 实现了通信透明性,解耦了通信细节。
Client-Dispatcher-Server (3.6.2) 提供位置透明性,并隐藏建立通信连接的细节。 客户端服务器之间添加分派器 (Dispatcher),利用名称服务定位服务器并转发请求。 应用方向: 分布式服务定位,RPC系统。 优点: 位置透明性,隐藏通信细节。
Publisher-Subscriber (3.6.3) 帮助相互协作的组件状态保持同步。 发布者维护并通知所有订阅者其状态变更。 应用方向: 事件驱动系统,MVC模式中模型与视图的同步。 优点: 对象间松耦合,支持广播通信。

第4章 成例(Idioms)

成例是最低抽象层次的模式,通常是语言特定的编程技巧。

Counted Pointer(引用计数指针,C++成例)

总结项 内容
模式总结/定义 一种C++编程成例,用于简化动态分配的共享对象的内存管理。
解决问题 避免在C++中使用裸指针进行动态分配的共享对象时,容易出现的内存泄漏和多重删除问题。
模式架构 句柄类 (Handle) 作为用户接口,内部包含指向实体类 (Body) 的指针。实体类中嵌入了一个引用计数。句柄的构造、赋值、复制和析构操作自动维护引用计数。
优缺点总结 优点: 实现了自动内存管理,简化了C++中共享对象的生命周期管理;避免了不必要的复制,提高了效率。 缺点: 引入了额外的引用计数开销;无法解决循环引用问题。
可能的应用方向 C++中任何需要共享和自动管理资源(如大型对象、句柄)的场景,类似于现代C++中的 std::shared_ptr 的思想。

总结与体会

这本书系统地介绍了从宏观架构到微观实现的模式,为我打开了软件架构的大门。特别是理解架构模式,让我明白了如何从一开始就规划系统的整体结构(如选择Layers来划分职责或选择Broker来处理分布式问题),这是初级工程师向高级进阶的必经之路。未来的工作中,我将努力在具体设计中识别和应用这些模式,并通过实践深入理解每个模式的优缺点权衡取舍,避免“为了模式而模式”。

Comment