23种设计模式
2025-04-13 23:34:36 0 举报
AI智能生成
设计模式是一套被反复使用、多数人知晓、经过分类编目、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。核心内容通常涉及创建型、结构型和行为型三类设计模式。 文件类型描述通常涉及源代码文件、脚本文件、配置文件等。设计模式与文件类型的关联性在于其在不同文件类型中的应用,如创建型模式多用于源代码文件中,以封装对象创建逻辑。 修饰语如“灵活、可扩展、易维护”等,常用来强调设计模式带来的积极影响。 例如,可用以下格式描述装饰者模式:“装饰者模式是一种结构型设计模式,允许向一个现有的对象添加新的功能,同时又不改变其结构。它提供了一种比继承更有弹性的替代方案。它在提高文件类型如类库、接口中对象功能时尤为有用。代码实现保持了灵活性、可扩展性,是‘敏捷开发’的典型应用实例。”
作者其他创作
大纲/内容
创建型模式
单例模式
特点
创建某个类的实例,该类的实例在系统中只有这一份
8种实现方式(枚举、内部静态类、DCL双重检测锁等)
案例
java.lang.Runtime(饿汉式)
应用场景
需要全局唯一控制的资源(如配置管理器、线程池、缓存)
避免重复创建开销大的对象(如数据库连接池)
简单工厂模式
特点
由工厂创建出产品类,客户端不用创建产品,直接从工厂获取
实现客户端和产品创建的解耦,产品的创建细节只在工厂里进行
案例
计算器工厂根据运算符创建运算对象
日志工厂根据日志类型创建日志处理器
应用场景
对象创建逻辑简单且变化较少的场景
客户端希望屏蔽对象创建细节,直接使用产品的场景
抽象工厂模式
特点
将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类(工厂簇)
根据创建对象类型使用对应的工厂子类
案例
跨平台UI组件工厂(如Windows和Mac的按钮、文本框等组件族)
不同数据库(MySQL、Oracle)的连接工厂及相关对象
应用场景
系统需要多个产品族,且产品族内部对象之间有依赖关系
产品族扩展时,只需新增具体工厂,不修改现有代码
原型模式
特点
该类的对象在系统中存在多份,通过复制现有对象创建新实例
实现方式
浅拷贝(默认,基本数据类型值传递,引用数据类型引用传递)
深拷贝(重写clone()方法或通过对象序列化与反序列化)
案例
简历模板复制生成个性化简历
游戏角色通过复制基础对象快速创建相似角色
应用场景
对象创建成本高(如初始化数据量大)的场景
需要保存对象状态快照(如深拷贝用于备份)
建造者模式
特点
一步一步创建一个复杂的对象
四个角色产品角色(Product)、抽象建造者(Builder)、具体建造者(ConcreteBuilder)、指挥者/经理(Director)
案例
建房子(过程打桩、砌墙、封顶;产品普通房、高楼、别墅;具体建造者各种房子的施工队;指挥者经理/包工头)
应用场景
对象构建步骤固定但参数多变(如配置类、复杂对象初始化)
需要链式调用或分步配置的场景(如SQL语句构建器)
结构型模式
适配器模式
特点
兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作
客户端可以通过适配器有选择地使用目标接口的方法(接口适配器)
分类
类适配器(继承适配器继承了目标对象类)
对象适配器(聚合适配器中聚合了目标对象)
接口适配器(实现目标对象是接口,适配器定义为抽象类实现该接口)
案例
WindowAdapter(窗口适配器类,简化窗口监听事件实现)
应用场景
复用旧类库或第三方接口,使其符合当前系统的接口需求
简化接口调用,仅暴露客户端需要的方法(如接口适配器过滤无关方法)
桥接模式
特点
把抽象(Abstraction)与行为实现(Implementation)分离开,保持各部分的独立性以及功能扩展
通过聚合关系关联抽象和实现,而非继承
案例
不同品牌、不同类型的手机实现同样的功能(品牌以聚合的形式加入手机中)
应用场景
抽象和实现均可能独立变化(如多维度扩展)
避免多层继承导致的类爆炸(如“品牌×类型”组合)
装饰者模式
特点
动态的将新功能附加到对象上,不修改原对象
支持多层嵌套装饰(如打包快递,一层一层地给物品添加外层包装)
案例
星巴克咖啡添加奶泡、糖浆等配料
应用场景
需要灵活扩展对象功能,且功能可动态组合(如日志、缓存、安全校验等附加功能)
避免通过继承扩展导致子类膨胀(每个功能组合都创建子类)
组合模式
特点
依据树形结构来组合对象,用来表示部分以及整体层次
用户对单个对象和组合对象的访问具有一致性
案例
学校、院、系的树形组织结构
应用场景
数据结构为树形层次(如菜单、组织架构、文件系统)
需要统一处理单个对象和组合对象的操作(如计算总大小、遍历元素)
外观模式
特点
屏蔽内部子系统的细节,简化用户操作
定义一个一致的接口,聚合各个子系统,调用端只需关心这个接口的调用
案例
家庭影院,一个遥控器控制各个电器
对接旧项目时提供统一API,隐藏底层复杂调用
应用场景
子系统逻辑复杂,客户端需要简单入口(如第三方库封装、微服务网关)
简化跨模块调用,减少客户端与子系统的耦合
享元模式
特点
运用共享技术,有效地支持大量细粒度的对象
池化技术(String常量池、数据库连接池、线程池等),解决重复对象的内存浪费问题
案例
String常量池(相同字符串字面量共享同一对象)
应用场景
大量细粒度对象(如文本字符、图表元素)存在重复实例
需要优化内存使用,共享内部状态(不变部分),外部状态动态传入
代理模式
特点
封装目标对象,并添加额外的功能,对客户端提供更多更优的服务
分类静态代理、动态代理
案例
远程代理处理网络通信细节,客户端通过代理访问远程对象
虚拟代理延迟加载图片,先显示占位符再替换真实图片
应用场景
需要控制对象访问(如权限校验、延迟加载、日志记录)
目标对象不可直接访问(如远程对象、创建成本高的对象)
行为型模式
模板方法模式
特点
定义了操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤
一般模板方法都加上final关键字,防止子类重写模板方法
案例
制作豆浆(流程选材→添加配料→浸泡→放到豆浆机打碎,子类实现“添加配料”步骤)
应用场景
算法步骤固定,但部分步骤需子类个性化实现(如文件解析流程、流程审批模板)
提取公共逻辑到父类,避免子类重复代码
命令模式
特点
消除了请求发送者与请求接收者之间的耦合,对象之间的调用关系更加灵活
命令以对象的形式存在,起到了纽带桥梁的作用
空命令省去判空操作
案例
遥控器按钮对应命令对象,控制电器(接收者)操作
应用场景
需要解耦请求发送者和接收者(如遥控器控制不同设备)
支持命令的撤销、重做、队列执行(如文本编辑器撤销功能)
访问者模式
特点
封装一些施加于某种数据结构元素之上的操作
适用于数据结构相对稳定的系统,解耦数据结构和作用于结构上的操作
案例
购物车计算总价、统计折扣(操作作用于商品集合)
组装电脑时对不同组件(CPU、显卡)执行不同操作
应用场景
数据结构稳定(如XML树、数据库表),需频繁新增操作(统计、转换、验证)
需要对不同元素类型(如文件、目录)执行不同操作
迭代器模式
特点
提供一种遍历集合元素的统一接口,隐藏集合内部数据结构(如数组、链表)
案例
Java集合框架中的Iterator接口统一遍历List、Set等集合
应用场景
集合类需要支持多种遍历方式(正向、反向、过滤遍历)
客户端无需关心集合内部实现,统一使用迭代器接口
观察者模式
特点
对象之间多对一依赖,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化
案例
气象站发布气象数据,通知所有订阅的客户端(如手机App、网页)
应用场景
事件驱动场景(如消息订阅、状态监控、通知推送)
需要一对多广播,观察者可动态添加/删除(如股票行情通知)
中介者模式
特点
封装一系列的对象交互,使各个对象不需要显式地相互引用,从而使其解耦
案例
聊天室中用户通过服务器(中介者)转发消息,不直接通信
应用场景
对象间交互复杂(网状依赖),通过中介者简化为星型结构
系统需要解耦,避免修改一个对象影响多个其他对象(如GUI组件间的交互)
备忘录模式
特点
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,支持状态恢复
案例
游戏角色生命值的保存及恢复(存档与读档)
应用场景
需要支持撤销、回滚操作(如编辑器、事务管理)
保存对象历史状态快照,且不希望外部直接访问对象内部数据
解释器模式
特点
给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
案例
编译器、运算表达式计算、正则表达式解析
应用场景
特定领域语言(DSL)解析(如SQL、数学公式、机器人指令)
需要灵活定义文法规则或频繁修改解析逻辑的场景
状态模式
特点
解决对象在多种状态转换时,需要对外输出不同的行为的问题,状态和行为一一对应,状态之间可以相互转换
案例
抽奖活动根据用户积分状态(未达标、达标、已抽奖)显示不同的抽奖按钮逻辑
应用场景
对象状态较多且状态变化影响行为(如订单状态待支付、已支付、已发货)
避免大量条件判断,将状态逻辑封装为独立状态类
策略模式
特点
定义算法族(策略组),分别封装起来,可以互相替换,算法的变化独立于使用算法的客户
方便扩展、方便维护
案例
员工年假年终奖根据不同职位(普通员工、经理、高管)采用不同的计算策略
应用场景
算法需灵活切换或扩展(如排序、加密、优惠计算)
避免大量条件判断,将每种算法封装为独立策略类
职责链模式
特点
为请求创建了一个接收者对象的链,请求的发送者和接收者解耦
通常每个接收者都包含对另一个接收者的引用,最后一个接收者中包含第一个接收者形成环路
案例
采购审批流程(员工提交申请,依次由组长、经理、总监审批)
应用场景
请求处理有多个环节,且环节顺序或组合可动态调整(如审批流程、日志处理)
需要解耦请求发送者与具体接收者,支持链式处理(如异常处理链)
0 条评论
下一页