(每日一问)设计模式:如何通俗理解常见的设计模式?


一、创建型模式

创建型模式专注于对象的创建过程,它们提供了灵活而高效的创建对象的方式。

1. 单例模式

说明:单例模式确保一个类只有一个实例,并提供一个全局访问点。可以把它想象成一个全局的控制台,整个系统中只有一个控制台实例。

举例:想象你在家里有一个Wi-Fi路由器。家里的所有设备都通过这个唯一的路由器连接到网络,整个家里只有这一个路由器。

应用场景:适用于需要保证全局唯一实例的场合,如数据库连接池、日志记录器或系统配置管理器。

2. 工厂方法模式

说明:工厂方法模式定义一个用于创建对象的接口,但让子类决定要实例化哪个类。可以把它看作一个制造厂,不同的原料会生产出不同的产品。

举例:假设你有一家披萨店,你可以根据顾客的口味制作不同口味的披萨。每种披萨都是一个不同的类,通过工厂方法选择并制作相应的披萨。

应用场景:适用于需要在运行时决定创建哪个类的实例的场合,如创建不同类型的文档(如PDF、Word)或根据配置选择不同的数据库连接。

3. 抽象工厂模式

说明:抽象工厂模式提供一个接口,用来创建相关或依赖的对象,而无需指定它们具体的类。可以把它理解为一个更高级的制造厂,可以生产一整套相关的产品。

举例:想象你进入一家家具商店,商店提供不同风格的家具套装,如现代风格、古典风格等。每种风格的家具套装包括沙发、茶几和餐桌等一系列家具。

应用场景:适用于需要创建一系列相关或依赖对象的场合,如构建跨平台的UI工具包,不同的UI工具包为不同的操作系统提供一致的界面。

4. 生成器模式

说明:生成器模式将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。你可以把它理解为组装玩具的过程,不同的零件组合方式可以组装出不同的玩具。

举例:例如,搭建乐高积木。你可以根据说明书,选择不同的积木组合,搭建出汽车、房子或者飞机。

5. 原型模式

说明:原型模式通过复制现有对象来创建新的对象,而不是直接实例化类。可以把它看作是复印机,通过复印机你可以快速复制出与原件一样的文档。

举例:想象你有一件喜欢的衣服,你可以找个裁缝复制一件完全一样的,而不是从头开始设计和制作。

6. 创建型模式总结表

二、结构型模式

结构型模式关注对象之间的组合或组织,它们提供了一种更优雅的方式来组织代码结构。

1. 适配器模式

说明:适配器模式将一个类的接口转换成客户希望的另一个接口,使原本不兼容的类可以一起工作。可以把它看作是插头转换器。

举例:你在国外旅行时,需要一个插头转换器才能使用当地的电源插座,这样你就可以继续使用自己的电子设备。

应用场景:适用于需要将现有类集成到新系统中,但接口不兼容的场合,如将旧系统的API集成到新系统中,或将第三方库的接口与本地系统接口适配。

2. 桥接模式

说明:桥接模式将抽象部分与实现部分分离,使它们可以独立变化。可以把它想象成桥梁,连接两座孤立的岛屿。

举例:想象你有一个遥控车,不同的遥控器可以控制不同类型的车子。你可以使用相同的遥控器控制跑车、卡车等,而不用关心车子的内部实现。

应用场景:适用于需要跨多个平台或维度独立变化的场合,如图形界面的平台无关性、设备控制系统中不同设备的控制逻辑分离。

3. 装饰器模式

说明:装饰器模式动态地给对象添加一些额外的职责,就增加功能而言,比生成子类更灵活。可以把它看作是给蛋糕加层。

举例:比如,你买了一个基础款的蛋糕,你可以根据自己的喜好选择添加巧克力、草莓或者奶油等装饰,让蛋糕变得更特别。

应用场景:适用于需要在不修改类代码的情况下动态扩展功能的场合,如为文本编辑器增加额外的文本处理功能,或者为图形对象增加额外的装饰。

4. 外观模式

说明:外观模式为子系统中的一组接口提供一个一致的界面,定义一个高层接口使子系统更易使用。可以把它看作是外壳包装。

举例:就像你买了一台新电视,使用遥控器可以轻松控制电视的开关、音量、频道切换等,而不需要去手动调整每个内部部件。

应用场景:适用于需要简化复杂系统接口的场合,如简化数据库操作、简化多个子系统的操作步骤,或者为复杂的操作流程提供简单的接口。

5. 享元模式

说明:享元模式通过共享已经存在的对象来减少创建对象的数量,以节省内存。可以把它看作是共享单车系统。

举例:在共享单车系统中,用户使用相同的共享单车,节省了制造和管理每个用户独立拥有的单车的资源。

应用场景:适用于大量细粒度对象的共享场合,如在游戏开发中共享图形对象或在文本编辑器中共享字符格式。

6. 代理模式

说明:代理模式为其他对象提供一种代理以控制对这个对象的访问。可以把它看作是代理人。

举例:假设你需要办理一项业务,但你很忙,于是你请了一个代理人来帮你处理这个业务。代理人就是你的代理模式实现。

应用场景:适用于需要控制访问权限的场合,如远程代理控制远程对象的访问,虚拟代理控制资源的延迟加载,或保护代理控制敏感对象的访问。

7. 结构型模式总结表

三、行为型模式

行为型模式关注对象之间的通信与合作,帮助对象更好地协同工作。

1. 责任链模式

说明:责任链模式使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合在一起。可以把它看作是传递责任的链条。

举例:比如你在公司提出一个申请,这个申请会先经过部门主管,如果主管无法批准,则会传递给总监,最后可能由经理来处理。

应用场景:适用于需要将请求处理责任分布到多个对象的场合,如审批流程、日志记录系统(不同级别的日志处理)等。

2. 命令模式

说明:命令模式将请求封装成对象,使得可以用不同的请求对客户进行参数化。可以把它想象成遥控器按钮。

举例:遥控器上的每个按钮都对应一个命令,比如开电视、调节音量,这些命令都是独立的对象,你可以根据需要随时调用。

应用场景:适用于需要对一系列操作进行参数化或队列化的场合,如事务性操作、宏命令实现、GUI按钮事件处理。

3. 解释器模式

说明:解释器模式定义了一种语言的文法表示,并定义了一个解释器来解释语言中的句子。可以把它看作是翻译器。

举例:比如你在学习一门新语言,你可以使用字典(解释器)来查找每个单词的含义,从而理解整个句子的意思。

应用场景:适用于需要解析和执行语言或表达式的场合,如编程语言的解释器、脚本引擎、正则表达式引擎。

4. 迭代器模式

说明:迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部的表示。可以把它看作是播放列表。

举例:就像你在音乐播放器中创建了一个播放列表,迭代器模式让你可以一个接一个地播放列表中的每首歌,而不用关心播放列表如何实现。

应用场景:适用于需要顺序访问集合对象的场合,如遍历集合中的元素、在文件系统中顺序访问文件或目录。

5. 中介者模式

说明:中介者模式用一个中介对象来封装一系列对象的交互,使各对象不需要显式地相互引用。可以把它看作是协调者。

举例:想象一个项目经理协调团队成员的工作,成员们通过项目经理沟通,而不是直接与其他所有成员联系。

应用场景:适用于需要简化多个对象之间复杂交互的场合,如GUI组件之间的交互、航空管制系统中的飞机间通信。

6. 备忘录模式

说明:备忘录模式在不破坏封装性的前提下,捕获并保存一个对象的内部状态,以便以后恢复它。可以把它看作是存档功能。

举例:就像你在游戏中保存了一个存档,可以在以后恢复到当时的游戏状态继续游戏。

应用场景:适用于需要保存和恢复对象状态的场合,如撤销操作、事务回滚、游戏进度保存。

7. 观察者模式

说明:观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。可以把它看作是订阅机制。

举例:比如你订阅了一个新闻频道,当频道发布新消息时,你会立即收到通知。

应用场景:适用于需要自动通知变化的场合,如事件监听机制、发布-订阅系统、GUI组件之间的依赖更新。

8. 状态模式

说明:状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。可以把它想象成变色龙。

举例:比如,咖啡机在不同状态下会有不同的行为,等待投币时,它会提示你投币;投币后,它会显示可选饮料;饮料选择后,它开始制作咖啡。

应用场景:适用于对象行为随状态变化而变化的场合,如有限状态机实现、基于状态的用户界面流程、文档编辑器中的编辑状态。

9. 策略模式

说明:策略模式定义一系列算法,将每一个算法封装起来,并使它们可以相互替换。可以把它看作是工具箱。

举例:假设你有一个修理工具箱,里面有各种各样的工具(算法),你可以根据具体需求选择使用不同的工具。

应用场景:适用于需要动态选择算法的场合,如数据排序算法的选择、支付方式选择、路径查找算法的切换。

10. 模板方法模式

说明:模板方法模式定义一个操作中的算法骨架,而将一些步骤延迟到子类中。可以把它看作是食谱。

举例:就像你按照食谱做菜,食谱定义了做菜的步骤(算法骨架),但具体的食材和调味品选择可以根据自己的口味调整。

应用场景:适用于需要定义操作通用步骤并允许子类自定义部分行为的场合,如算法的通用框架、处理流程中的可变步骤。

11. 访问者模式

说明:访问者模式在不改变数据结构的前提下,增加作用于对象结构上的新操作。可以把它看作是游客参观不同景点。

举例:就像你在旅游时可以选择参观不同的景点(对象),导游(访问者)会在每个景点提供不同的信息和体验。

应用场景:适用于需要在不改变类结构的情况下增加新操作的场合,如对象结构的处理、编译器中的语法树处理。

12. 行为型模式总结表

四、结论

设计模式虽然听起来复杂,但通过日常生活中的比喻可以更容易地理解它们。无论是创建型、结构型还是行为型模式,它们都帮助开发人员更好地设计软件,解决实际问题。在日常开发中,理解并应用这些模式,能够提高代码的质量和开发效率。


08-28 04:42