【软件设计】23 种设计模式解析与实践指南

ops/2025/3/15 13:59:46/

引言

        设计模式(Design Pattern)是软件开发中反复出现的问题的解决方案,由 Erich Gamma 等四人组(GoF)在 1994 年系统化提出。

        在软件开发领域,设计模式是解决常见软件设计问题的可复用方案。它们就像是建筑师手中的蓝图,帮助开发者构建高效、可维护和可扩展的软件系统。掌握多种设计模式,能够让开发者在面对不同的项目需求时,灵活地选择合适的模式,从而提高软件的质量和开发效率。

一、设计模式分类

分类设计模式名称
创建型模式单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
结构型模式适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、代理模式
行为型模式责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

二、定义与描述

设计模式定义与描述抽象背景适用场景与现实问题解决
单例模式确保类仅有一个实例,提供全局访问点资源管理(如日志、配置、数据库连接)任务管理器、打印机队列(全局唯一控制)
工厂方法模式定义创建对象的接口,子类决定实例化哪个类统一对象创建接口,应对产品族扩展框架扩展(Spring BeanFactory)、日志系统多实现
抽象工厂模式提供创建相关或依赖对象的接口,无需指定具体类管理产品族,保证客户端与具体实现解耦跨平台 UI 组件(如按钮、文本框)创建
建造者模式将复杂对象的构建与表示分离,允许相同构建过程创建不同表示分步构建复杂对象(如配置文件、SQL 查询)游戏角色创建(属性分步设置)、套餐组合(如汉堡套餐)
原型模式通过复制现有实例创建新对象对象创建成本高(如数据库连接池预热)快速克隆对象(如游戏存档、缓存数据)
适配器模式转换类接口,使其能协同工作旧系统与新接口兼容(如不同支付方式)第三方 API 集成(支付网关适配不同银行接口)
桥接模式分离抽象与实现,使两者独立变化多维度扩展(如形状与颜色)跨平台开发(操作系统与 GUI 组件解耦)
组合模式将对象组合成树形结构以表示整体 - 部分层次统一处理单个对象与组合对象文件系统目录管理、企业组织架构表示
装饰器模式动态添加职责,不改变原类结构功能扩展(如咖啡加配料)日志增强(记录执行时间、异常信息)
外观模式提供统一接口简化子系统交互复杂系统对外暴露简单接口支付系统封装(整合银行、风控、日志等模块)
享元模式共享大量细粒度对象以节省内存内存优化(如文本编辑器字符渲染)游戏角色池(复用相同模型的角色)
代理模式控制对真实对象的访问延迟加载、访问控制(如权限验证)虚拟代理(图片懒加载)、远程代理(跨网络调用)
责任链模式将请求沿处理链传递,直到有对象处理它请求处理者动态组合(如审批流程)请假审批链(主管→部门经理→CEO)
命令模式将请求封装为对象,支持撤销、排队等操作操作封装与参数化(如 GUI 命令)游戏操作记录(支持撤销 / 重做)、任务队列
解释器模式定义语言的文法及解释器特定领域语言解析(如正则表达式)数学表达式计算、自定义配置语言解析
迭代器模式提供顺序访问聚合对象元素的方法遍历方式与数据结构解耦集合遍历(如 Java 的 Iterator)、树结构遍历
中介者模式用中介对象封装对象间交互减少对象间直接依赖(如 MVC 中的 Controller)聊天室消息转发、UI 组件交互(按钮与文本框解耦)
备忘录模式捕获并恢复对象状态状态保存与恢复(如游戏存档)编辑器撤销功能、数据库事务回滚
观察者模式对象状态变化时通知依赖它的对象发布 - 订阅机制(如事件监听)股票价格实时更新、消息推送系统
状态模式对象行为随状态改变而变化状态驱动的行为(如订单状态机)电梯状态控制(运行 / 停止 / 维修)、工作流引擎
策略模式定义算法族,允许在运行时选择算法算法动态切换(如排序策略)支付方式选择(支付宝 / 微信 / 信用卡)、日志级别控制
模板方法模式定义操作步骤,子类实现具体步骤流程固定但部分步骤可变(如数据处理流程)电商订单处理流程(支付→发货→通知)、测试用例基类
访问者模式封装作用于对象结构的操作数据结构与操作分离(如报表生成)编译器语法树遍历、XML 文档解析

三、综合对比

设计模式优点缺点升级版线程安全支持核心应用场景
单例模式控制实例数量,节省资源全局状态影响测试,扩展性差枚举单例、线程安全懒加载需手动实现日志系统、配置管理、数据库连接池
工厂方法模式解耦对象创建与使用,支持扩展子类爆炸问题结合依赖注入框架扩展(Spring BeanFactory)、日志系统多实现
抽象工厂模式统一管理产品族,保证兼容性新增产品类型需修改抽象类泛型工厂跨平台 UI 组件(按钮、文本框)创建
建造者模式分步构建复杂对象,灵活性高增加类数量流式 API游戏角色创建、套餐组合(汉堡 + 饮料)
原型模式快速克隆对象,减少创建成本深拷贝可能引发性能问题序列化克隆游戏存档、缓存数据快速复制
适配器模式兼容不兼容接口,复用旧代码增加一层间接性双向适配器第三方 API 集成(支付网关适配不同银行)
桥接模式分离抽象与实现,支持独立扩展设计复杂度高结合依赖注入跨平台开发(操作系统与 GUI 组件解耦)
组合模式统一处理单个对象与组合对象树形结构遍历可能复杂透明组合文件系统目录管理、企业组织架构表示
装饰器模式动态扩展功能,不改变原类结构多层装饰影响性能链式调用、注解增强日志增强(记录执行时间、异常信息)
外观模式简化子系统交互,降低依赖可能成为性能瓶颈微服务网关支付系统封装(整合银行、风控、日志)
享元模式共享对象节省内存增加系统复杂度结合缓存机制游戏角色池(复用相同模型)、文本编辑器字符渲染
代理模式控制访问,支持延迟加载增加代理类动态代理(如 Java 反射)图片懒加载、远程服务调用
责任链模式请求处理者动态组合,扩展性强可能导致请求未被处理动态责任链请假审批链(主管→部门经理→CEO)
命令模式支持撤销、重做、日志记录命令类数量多结合备忘录模式游戏操作记录、任务队列
解释器模式自定义语言解析灵活复杂文法性能差结合语法树优化数学表达式计算、配置语言解析
迭代器模式遍历方式与数据结构解耦可能限制遍历方式双向迭代器集合遍历(Java Iterator)、树结构遍历
中介者模式减少对象间直接依赖中介者可能过度复杂事件总线聊天室消息转发、UI 组件交互
备忘录模式保存与恢复对象状态内存消耗大差异存储编辑器撤销功能、数据库事务回滚
观察者模式支持发布 - 订阅机制,松耦合通知顺序难以控制响应式编程(RxJava)股票价格更新、消息推送系统
状态模式状态驱动行为,避免条件判断状态类数量多状态机框架电梯状态控制、工作流引擎
策略模式动态切换算法,扩展性强客户端需了解所有策略策略工厂支付方式选择、日志级别控制
模板方法模式固定流程,子类实现细节子类必须实现所有抽象方法钩子方法增强订单处理流程(支付→发货→通知)、测试用例基类
访问者模式数据结构与操作分离新增操作需修改所有访问者双分派机制编译器语法树遍历、XML 文档解析

 四、综合应用

(一)、文档编辑器

 场景组合模式 + 装饰器模式 + 策略模式 + 观察者模式

 文档编辑器(树形结构管理 + 格式装饰 + 保存策略 + 实时预览)

// 组合模式:文档结构
interface DocumentComponent {void print();void accept(Visitor visitor);
}class TextElement implements DocumentComponent {private String content;public TextElement(String content) { this.content = content; }public void print() { System.out.println(content); }public void accept(Visitor visitor) { visitor.visit(this); }
}class CompositeElement implements DocumentComponent {private List<DocumentComponent> children = new ArrayList<>();public void add(DocumentComponent component) { children.add(component); }public void print() { children.forEach(DocumentComponent::print); }public void accept(Visitor visitor) { visitor.visit(this); }
}// 装饰器模式:格式增强
abstract class FormatDecorator implements DocumentComponent {protected DocumentComponent component;public FormatDecorator(DocumentComponent component) { this.component = component; }public abstract void print();public void accept(Visitor visitor) { component.accept(visitor); }
}class BoldDecorator extends FormatDecorator {public BoldDecorator(DocumentComponent component) { super(component); }public void print() { System.out.printf("<b>%s</b>", component); }
}// 策略模式:保存策略
interface SaveStrategy {void save(DocumentComponent doc);
}class HtmlSaveStrategy implements SaveStrategy {public void save(DocumentComponent doc) {System.out.println("Saving as HTML...");doc.accept(new HtmlVisitor());}
}// 观察者模式:实时预览
interface Observer {void update(DocumentComponent doc);
}class PreviewWindow implements Observer {public void update(DocumentComponent doc) {System.out.println("Preview updated:");doc.print();}
}class DocumentManager implements Subject {private List<Observer> observers = new ArrayList<>();private DocumentComponent document;public void attach(Observer observer) { observers.add(observer); }public void notifyObservers() { observers.forEach(o -> o.update(document)); }public void setDocument(DocumentComponent doc) {this.document = doc;notifyObservers();}
}

 类图:

时序图: 

 典型组合方案

        树形结构 + 动态扩展:组合模式 + 装饰器模式

        流程控制 + 算法选择:责任链模式 + 策略模式

        数据遍历 + 操作分离:迭代器模式 + 访问者模式

 (二)、电商订单处理

  场景组合模式 + 责任链模式 + 策略模式

  电商订单处理(订单拆分 → 多级审批 → 支付方式选择)

// 组合模式:订单结构
class OrderComponent {protected double amount;public abstract void process();
}class CompositeOrder extends OrderComponent {private List<OrderComponent> children = new ArrayList<>();public void add(OrderComponent child) { children.add(child); }public void process() {children.forEach(OrderComponent::process);}
}// 责任链模式:审批链
abstract class Approver {protected Approver successor;public void setSuccessor(Approver successor) { this.successor = successor; }public abstract void approve(OrderComponent order);
}class ManagerApprover extends Approver {public void approve(OrderComponent order) {if (order.amount < 1000) {System.out.println("Manager approved");} else if (successor != null) {successor.approve(order);}}
}// 策略模式:支付方式
interface PaymentStrategy {void pay(double amount);
}class CreditCardStrategy implements PaymentStrategy {public void pay(double amount) {System.out.printf("Paid $%.2f via Credit Card%n", amount);}
}

 类图:

时序图: 

(三)、文件系统遍历

 场景组合模式 + 迭代器模式 + 访问者模式

文件系统遍历(目录结构 → 迭代访问 → 统计文件信息)

// 组合模式:文件系统节点
interface FileSystemNode {void accept(FileVisitor visitor);
}class File implements FileSystemNode {private String name;public void accept(FileVisitor visitor) { visitor.visit(this); }
}class Directory implements FileSystemNode {private List<FileSystemNode> children = new ArrayList<>();public void add(FileSystemNode node) { children.add(node); }public void accept(FileVisitor visitor) {visitor.visit(this);children.forEach(n -> n.accept(visitor));}
}// 迭代器模式:遍历器
class FileSystemIterator implements Iterator<FileSystemNode> {private Stack<FileSystemNode> stack = new Stack<>();public FileSystemIterator(FileSystemNode root) {stack.push(root);}public boolean hasNext() {return !stack.isEmpty();}public FileSystemNode next() {FileSystemNode node = stack.pop();if (node instanceof Directory) {((Directory) node).getChildren().forEach(stack::push);}return node;}
}// 访问者模式:文件统计
class FileVisitor {public void visit(File file) {System.out.println("File: " + file.getName());}public void visit(Directory directory) {System.out.println("Directory: " + directory.getName());}
}

类图:

时序图:

典型组合方案

        树形结构 + 动态扩展:组合模式 + 装饰器模式

        流程控制 + 算法选择:责任链模式 + 策略模式

        数据遍历 + 操作分离:迭代器模式 + 访问者模式


http://www.ppmy.cn/ops/165958.html

相关文章

SANS 网络安全 网络安全三件套

基本设置篇      一、在线安全的四个误解     Internet实际上是个有来有往的世界&#xff0c;你可以很轻松地连接到你喜爱的站点&#xff0c;而其他人&#xff0c;例如黑客也很方便地连接到你的机器。实际上&#xff0c;很多机器都因为自己很糟糕的在线安全设置无意间在…

iPhone 17系列新机模上手,横向矩阵镜头+超薄机身,清新白色设计

在科技飞速发展的当下,智能手机市场的竞争愈发激烈,每一次新品的发布都吸引着全球消费者的目光。而苹果公司的iPhone系列,作为行业的标杆,更是备受关注。近期,iPhone 17系列新机模的曝光,犹如一颗重磅炸弹,在科技圈掀起了一阵热潮。今天,就让我们一起深入了解这款还未正…

使用服务器如何DNS呢

莱卡云服务器 DNS 配置指南 一、配置云服务器本地 DNS ‌修改网络配置文件‌ ‌Ubuntu/Debian‌&#xff1a; bashCopy Code sudo nano /etc/network/interfaces # 添加或修改 DNS 配置 dns-nameservers 8.8.8.8 8.8.4.4 *&#xff08;保存后重启网络服务&#xf…

【GB28181】RTSP服务器传输AAC音频

概述 实现一个简单的RTSP服务器&#xff0c;主要用于从本地AAC文件读取音频数据&#xff0c;然后通过RTP协议实时传输AAC音频流。整体结构和H264视频流服务器结构相似 ADTS头部 结构体分析 该结构体主要用于描述ADTS头部&#xff0c;该头部信息位于每个AAC音频帧之前&#xf…

[测试]软件测试的生命周期,bug的级别及生命周期

文章目录 1. 软件测试的生命周期2. BUG2.1 bug的概念2.2 描述bug的要素2.3 bug级别2.4 bug的生命周期2.5 与开发产生争执怎么办&#xff08;高频考题&#xff09; 1. 软件测试的生命周期 软件测试贯穿于软件的整个生命周期。 软件测试的生命周期是指测试流程&#xff0c;这个流…

stm32u5

//1 使能系统时钟 // 系统时钟初始化 - 不加入会报错 可以尝试一下 void SystemInit(void) { //对地址 0xE000ED88 的内容 进行修改: //将0X3向左移动20位 或上 0X3 向左移动22位 *(unsigned int*) 0xE000ED88|((3UL << 20U)|(3UL << 22U)); } int main() …

rust 中的package、crate、module

初学rust&#xff0c;对crate和mod的使用总是感到不太顺利&#xff0c;特此记录一下。 当我们用cargo 创建一个新项目时&#xff0c;默认就创建了一个package。 PS D:\test\rust_test> cargo new myproject Creating binary (application) myproject package note: see…

红色警戒2:共和国之辉红警语音台词是什么?

红警中的台词中其他台词的意思&#xff1a; 1、new construction ready: 新建造准备 2、building: 开始建造 3、construction complete: 建造完毕 4、on hold: 建造暂停 5、canceled: 建造取消 6、repairing: 修理 7、insufficienct fun: 资金短缺 8、low power: 电力不足 9、p…