(每日一问)设计模式:如何通俗理解常见的设计模式?
本文旨在通过日常生活中的类比来通俗地解释常见的设计模式,帮助读者理解这些模式的核心思想。文章将设计模式分为创建型、结构型和行为型三大类,每种模式都通过生活中的具体事例进行类比解释 ,方便读者更直观地掌握这些概念。需要注意的是,本文不会涉及具体的代码实现,具体的实例代码将会在其他文章中详细介绍。
文章目录
- (每日一问)设计模式:如何通俗理解常见的设计模式?
-
- 一、创建型模式
-
- [1. 单例模式](#1. 单例模式)
- [2. 工厂方法模式](#2. 工厂方法模式)
- [3. 抽象工厂模式](#3. 抽象工厂模式)
- [4. 生成器模式](#4. 生成器模式)
- [5. 原型模式](#5. 原型模式)
- [6. 创建型模式总结表](#6. 创建型模式总结表)
- 二、结构型模式
-
- [1. 适配器模式](#1. 适配器模式)
- [2. 桥接模式](#2. 桥接模式)
- [3. 装饰器模式](#3. 装饰器模式)
- [4. 外观模式](#4. 外观模式)
- [5. 享元模式](#5. 享元模式)
- [6. 代理模式](#6. 代理模式)
- [7. 结构型模式总结表](#7. 结构型模式总结表)
- 三、行为型模式
-
- [1. 责任链模式](#1. 责任链模式)
- [2. 命令模式](#2. 命令模式)
- [3. 解释器模式](#3. 解释器模式)
- [4. 迭代器模式](#4. 迭代器模式)
- [5. 中介者模式](#5. 中介者模式)
- [6. 备忘录模式](#6. 备忘录模式)
- [7. 观察者模式](#7. 观察者模式)
- [8. 状态模式](#8. 状态模式)
- [9. 策略模式](#9. 策略模式)
- [10. 模板方法模式](#10. 模板方法模式)
- [11. 访问者模式](#11. 访问者模式)
- [12. 行为型模式总结表](#12. 行为型模式总结表)
- 四、结论
一、创建型模式
创建型模式专注于对象的创建过程,它们提供了灵活而高效的创建对象的方式。
1. 单例模式
说明:单例模式确保一个类只有一个实例,并提供一个全局访问点。可以把它想象成一个全局的控制台,整个系统中只有一个控制台实例。
举例:想象你在家里有一个Wi-Fi路由器。家里的所有设备都通过这个唯一的路由器连接到网络,整个家里只有这一个路由器。
应用场景:适用于需要保证全局唯一实例的场合,如数据库连接池、日志记录器或系统配置管理器。
2. 工厂方法模式
说明:工厂方法模式定义一个用于创建对象的接口,但让子类决定要实例化哪个类。可以把它看作一个制造厂,不同的原料会生产出不同的产品。
举例:假设你有一家披萨店,你可以根据顾客的口味制作不同口味的披萨。每种披萨都是一个不同的类,通过工厂方法选择并制作相应的披萨。
应用场景:适用于需要在运行时决定创建哪个类的实例的场合,如创建不同类型的文档(如PDF、Word)或根据配置选择不同的数据库连接。
3. 抽象工厂模式
说明:抽象工厂模式提供一个接口,用来创建相关或依赖的对象,而无需指定它们具体的类。可以把它理解为一个更高级的制造厂,可以生产一整套相关的产品。
举例:想象你进入一家家具商店,商店提供不同风格的家具套装,如现代风格、古典风格等。每种风格的家具套装包括沙发、茶几和餐桌等一系列家具。
应用场景:适用于需要创建一系列相关或依赖对象的场合,如构建跨平台的UI工具包,不同的UI工具包为不同的操作系统提供一致的界面。
4. 生成器模式
说明:生成器模式将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。你可以把它理解为组装玩具的过程,不同的零件组合方式可以组装出不同的玩具。
举例:例如,搭建乐高积木。你可以根据说明书,选择不同的积木组合,搭建出汽车、房子或者飞机。
5. 原型模式
说明:原型模式通过复制现有对象来创建新的对象,而不是直接实例化类。可以把它看作是复印机,通过复印机你可以快速复制出与原件一样的文档。
举例:想象你有一件喜欢的衣服,你可以找个裁缝复制一件完全一样的,而不是从头开始设计和制作。
6. 创建型模式总结表
模式 | 主要特点 | 适用场景 |
---|---|---|
单例模式 | 确保一个类只有一个实例,并提供全局访问点 | 数据库连接池、日志记录器、系统配置管理器 |
工厂方法模式 | 定义创建对象的接口,让子类决定实例化哪个类 | 文档生成、数据库连接器的选择 |
抽象工厂模式 | 提供创建一系列相关或依赖对象的接口,避免指定具体的类 | 跨平台UI工具包、创建系列相关对象 |
生成器模式 | 将对象的构建过程与表示分离,同一构建过程可创建不同的对象 | 复杂文档构建、HTML页面生成、汽车模型创建 |
原型模式 | 通过复制现有对象创建新对象,避免直接实例化类 | 游戏中创建相似的NPC、图形应用中复制复杂图形对象 |
二、结构型模式
结构型模式关注对象之间的组合或组织,它们提供了一种更优雅的方式来组织代码结构。
1. 适配器模式
说明:适配器模式将一个类的接口转换成客户希望的另一个接口,使原本不兼容的类可以一起工作。可以把它看作是插头转换器。
举例:你在国外旅行时,需要一个插头转换器才能使用当地的电源插座,这样你就可以继续使用自己的电子设备。
应用场景:适用于需要将现有类集成到新系统中,但接口不兼容的场合,如将旧系统的API集成到新系统中,或将第三方库的接口与本地系统接口适配。
2. 桥接模式
说明:桥接模式将抽象部分与实现部分分离,使它们可以独立变化。可以把它想象成桥梁,连接两座孤立的岛屿。
举例:想象你有一个遥控车,不同的遥控器可以控制不同类型的车子。你可以使用相同的遥控器控制跑车、卡车等,而不用关心车子的内部实现。
应用场景:适用于需要跨多个平台或维度独立变化的场合,如图形界面的平台无关性、设备控制系统中不同设备的控制逻辑分离。
3. 装饰器模式
说明:装饰器模式动态地给对象添加一些额外的职责,就增加功能而言,比生成子类更灵活。可以把它看作是给蛋糕加层。
举例:比如,你买了一个基础款的蛋糕,你可以根据自己的喜好选择添加巧克力、草莓或者奶油等装饰,让蛋糕变得更特别。
应用场景:适用于需要在不修改类代码的情况下动态扩展功能的场合,如为文本编辑器增加额外的文本处理功能,或者为图形对象增加额外的装饰。
4. 外观模式
说明:外观模式为子系统中的一组接口提供一个一致的界面,定义一个高层接口使子系统更易使用。可以把它看作是外壳包装。
举例:就像你买了一台新电视,使用遥控器可以轻松控制电视的开关、音量、频道切换等,而不需要去手动调整每个内部部件。
应用场景:适用于需要简化复杂系统接口的场合,如简化数据库操作、简化多个子系统的操作步骤,或者为复杂的操作流程提供简单的接口。
5. 享元模式
说明:享元模式通过共享已经存在的对象来减少创建对象的数量,以节省内存。可以把它看作是共享单车系统。
举例:在共享单车系统中,用户使用相同的共享单车,节省了制造和管理每个用户独立拥有的单车的资源。
应用场景:适用于大量细粒度对象的共享场合,如在游戏开发中共享图形对象或在文本编辑器中共享字符格式。
6. 代理模式
说明:代理模式为其他对象提供一种代理以控制对这个对象的访问。可以把它看作是代理人。
举例:假设你需要办理一项业务,但你很忙,于是你请了一个代理人来帮你处理这个业务。代理人就是你的代理模式实现。
应用场景:适用于需要控制访问权限的场合,如远程代理控制远程对象的访问,虚拟代理控制资源的延迟加载,或保护代理控制敏感对象的访问。
7. 结构型模式总结表
模式 | 主要特点 | 适用场景 |
---|---|---|
适配器模式 | 将一个类的接口转换为客户希望的另一个接口,使不兼容的类协同工作 | 集成旧系统到新系统、接口不兼容的库适配 |
桥接模式 | 将抽象部分与实现部分分离,使它们可以独立变化 | 跨平台图形界面、设备控制系统的分离 |
装饰器模式 | 动态地给对象添加额外职责,比生成子类更灵活 | 动态扩展功能、增加文本处理功能、图形对象装饰 |
外观模式 | 为子系统中的一组接口提供一个一致的界面,简化系统的使用 | 简化数据库操作、简化子系统操作步骤、提供简单接口 |
享元模式 | 通过共享已有对象减少新对象的创建,节省内存 | 游戏中共享图形对象、文本编辑器中共享字符格式 |
代理模式 | 为其他对象提供一种代理,以控制对这个对象的访问 | 远程代理、虚拟代理、保护代理控制访问权限 |
以下是对博客中"行为型模式"部分的补充,包括应用场景的添加和总结表格的创建。 |
三、行为型模式
行为型模式关注对象之间的通信与合作,帮助对象更好地协同工作。
1. 责任链模式
说明:责任链模式使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合在一起。可以把它看作是传递责任的链条。
举例:比如你在公司提出一个申请,这个申请会先经过部门主管,如果主管无法批准,则会传递给总监,最后可能由经理来处理。
应用场景:适用于需要将请求处理责任分布到多个对象的场合,如审批流程、日志记录系统(不同级别的日志处理)等。
2. 命令模式
说明:命令模式将请求封装成对象,使得可以用不同的请求对客户进行参数化。可以把它想象成遥控器按钮。
举例:遥控器上的每个按钮都对应一个命令,比如开电视、调节音量,这些命令都是独立的对象,你可以根据需要随时调用。
应用场景:适用于需要对一系列操作进行参数化或队列化的场合,如事务性操作、宏命令实现、GUI按钮事件处理。
3. 解释器模式
说明:解释器模式定义了一种语言的文法表示,并定义了一个解释器来解释语言中的句子。可以把它看作是翻译器。
举例:比如你在学习一门新语言,你可以使用字典(解释器)来查找每个单词的含义,从而理解整个句子的意思。
应用场景:适用于需要解析和执行语言或表达式的场合,如编程语言的解释器、脚本引擎、正则表达式引擎。
4. 迭代器模式
说明:迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部的表示。可以把它看作是播放列表。
举例:就像你在音乐播放器中创建了一个播放列表,迭代器模式让你可以一个接一个地播放列表中的每首歌,而不用关心播放列表如何实现。
应用场景:适用于需要顺序访问集合对象的场合,如遍历集合中的元素、在文件系统中顺序访问文件或目录。
5. 中介者模式
说明:中介者模式用一个中介对象来封装一系列对象的交互,使各对象不需要显式地相互引用。可以把它看作是协调者。
举例:想象一个项目经理协调团队成员的工作,成员们通过项目经理沟通,而不是直接与其他所有成员联系。
应用场景:适用于需要简化多个对象之间复杂交互的场合,如GUI组件之间的交互、航空管制系统中的飞机间通信。
6. 备忘录模式
说明:备忘录模式在不破坏封装性的前提下,捕获并保存一个对象的内部状态,以便以后恢复它。可以把它看作是存档功能。
举例:就像你在游戏中保存了一个存档,可以在以后恢复到当时的游戏状态继续游戏。
应用场景:适用于需要保存和恢复对象状态的场合,如撤销操作、事务回滚、游戏进度保存。
7. 观察者模式
说明:观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。可以把它看作是订阅机制。
举例:比如你订阅了一个新闻频道,当频道发布新消息时,你会立即收到通知。
应用场景:适用于需要自动通知变化的场合,如事件监听机制、发布-订阅系统、GUI组件之间的依赖更新。
8. 状态模式
说明:状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。可以把它想象成变色龙。
举例:比如,咖啡机在不同状态下会有不同的行为,等待投币时,它会提示你投币;投币后,它会显示可选饮料;饮料选择后,它开始制作咖啡。
应用场景:适用于对象行为随状态变化而变化的场合,如有限状态机实现、基于状态的用户界面流程、文档编辑器中的编辑状态。
9. 策略模式
说明:策略模式定义一系列算法,将每一个算法封装起来,并使它们可以相互替换。可以把它看作是工具箱。
举例:假设你有一个修理工具箱,里面有各种各样的工具(算法),你可以根据具体需求选择使用不同的工具。
应用场景:适用于需要动态选择算法的场合,如数据排序算法的选择、支付方式选择、路径查找算法的切换。
10. 模板方法模式
说明:模板方法模式定义一个操作中的算法骨架,而将一些步骤延迟到子类中。可以把它看作是食谱。
举例:就像你按照食谱做菜,食谱定义了做菜的步骤(算法骨架),但具体的食材和调味品选择可以根据自己的口味调整。
应用场景:适用于需要定义操作通用步骤并允许子类自定义部分行为的场合,如算法的通用框架、处理流程中的可变步骤。
11. 访问者模式
说明:访问者模式在不改变数据结构的前提下,增加作用于对象结构上的新操作。可以把它看作是游客参观不同景点。
举例:就像你在旅游时可以选择参观不同的景点(对象),导游(访问者)会在每个景点提供不同的信息和体验。
应用场景:适用于需要在不改变类结构的情况下增加新操作的场合,如对象结构的处理、编译器中的语法树处理。
12. 行为型模式总结表
模式 | 主要特点 | 适用场景 |
---|---|---|
责任链模式 | 使多个对象都有机会处理请求,避免发送者与接收者耦合 | 审批流程、日志记录系统 |
命令模式 | 将请求封装为对象,支持参数化和队列化操作 | 事务性操作、宏命令、GUI按钮事件处理 |
解释器模式 | 定义语言的文法表示和解释器,用于解析和执行语言表达式 | 编程语言解释器、脚本引擎、正则表达式引擎 |
迭代器模式 | 顺序访问聚合对象的元素,不暴露其内部表示 | 遍历集合、文件系统访问、容器类遍历 |
中介者模式 | 用中介对象封装对象之间的交互,减少对象之间的直接引用 | GUI组件交互、航空管制系统 |
备忘录模式 | 保存并恢复对象的内部状态,支持撤销和恢复操作 | 撤销操作、事务回滚、游戏进度保存 |
观察者模式 | 定义一对多的依赖关系,当一个对象变化时通知依赖对象更新 | 事件监听机制、发布-订阅系统、GUI依赖更新 |
状态模式 | 允许对象在内部状态改变时改变其行为,模拟状态机的行为 | 有限状态机、状态驱动的流程、编辑器状态管理 |
策略模式 | 将算法封装为可互换的对象,支持动态选择算法 | 数据排序、支付方式选择、路径查找算法切换 |
模板方法模式 | 定义操作的通用步骤,允许子类定制部分步骤 | 算法框架、处理流程中的可变步骤 |
访问者模式 | 在不改变数据结构的前提下增加新操作,适用于对象结构处理 | 语法树处理、对象结构遍历 |
四、结论
设计模式虽然听起来复杂,但通过日常生活中的比喻可以更容易地理解它们。无论是创建型、结构型还是行为型模式,它们都帮助开发人员更好地设计软件,解决实际问题。在日常开发中,理解并应用这些模式,能够提高代码的质量和开发效率。
✨ 我是专业牛,一个渴望成为大牛🏆的985硕士🎓,热衷于分享知识📚,帮助他人解决问题💡,为大家提供科研、竞赛等方面的建议和指导🎯。无论是科研项目🛠️、竞赛🏅,还是图像🖼️、通信📡、计算机💻领域的论文辅导📑,我都以诚信为本🛡️,质量为先!🤝 如果你觉得这篇文章对你有所帮助,别忘了点赞👍、收藏📌和关注🔔哦!你的支持是我继续分享知识的动力🚀!✨ 如果你有任何问题或需要帮助,随时留言📬或私信📲,我都会乐意解答!😊