设计模式概览

embedded/2024/10/18 0:44:44/

设计模式是一种解决常见编程问题的经验总结,提供了代码的可重用性、可扩展性和可维护性。常见的设计模式有23个,主要分为三大类:创建型模式、结构型模式和行为型模式。下面是这三类设计模式的详细分类和讲解:

在这里插入图片描述

一、创建型模式

创建型模式主要处理对象的创建过程,提供了不同的方式来控制对象的创建,以提高灵活性和可复用性。

1. 单例模式(Singleton Pattern)

保证一个类仅有一个实例,并提供全局访问点。

  • 使用场景:资源管理器、日志系统、数据库连接池等。
  • 优点:减少内存开销,避免多次创建实例。
  • 缺点:容易造成全局状态,使得代码难以测试。
2. 工厂方法模式(Factory Method Pattern)

定义一个用于创建对象的接口,但让子类决定要实例化的类。
-使用场景:当一个类不知道它所需要创建的对象的具体类型时。
-优点:提高灵活性,使代码依赖于抽象而非具体类。
-缺点:增加类的数量,增加系统复杂性。

3. 抽象工厂模式(Abstract Factory Pattern)

提供一个接口,用于创建一系列相关或依赖的对象,而无需指定具体的类。
-使用场景:当系统需要与多个相关联的产品族打交道时。
-优点:易于扩展,满足"开放-关闭"原则。
-缺点:复杂度较高,扩展困难。

4. 建造者模式(Builder Pattern)

将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

  • 使用场景:构建复杂对象时,如HTML生成器、SQL查询构建器等。
  • 优点:使得创建过程更加清晰,可拆分步骤。
  • 缺点:产品变化多时,建造者类可能会变得庞大。
5. 原型模式(Prototype Pattern)

通过复制已有的实例来创建新对象,而不是通过实例化类来创建。

  • 使用场景:当对象的创建开销较大,且需要大量相似对象时。
  • 优点:避免重复初始化。
  • 缺点:深拷贝和浅拷贝的处理可能较复杂。

二、结构型模式

结构型模式关注类和对象的组合,主要目的是通过继承或组合的方式来获得新的功能。

1. 适配器模式(Adapter Pattern)

将一个类的接口转换成客户希望的另外一个接口,使得原本接口不兼容的类可以一起工作。

  • 使用场景:当现有类的接口与需求不符时,如将老系统接口适配新系统。
  • 优点:复用已有代码,增强代码兼容性。
  • 缺点:增加了系统的复杂性。
2. 桥接模式(Bridge Pattern)

将抽象部分与实现部分分离,使它们可以独立变化。

  • 使用场景:当一个类具有多个维度的变化时(如设备和操作系统)。
  • 优点:可以独立扩展抽象和实现部分。
  • 缺点:增加了系统的理解和设计难度。
3. 组合模式(Composite Pattern)

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

  • 使用场景:当系统需要表示树形结构时,如文件系统。
  • 优点:简化了客户端代码。
  • 缺点:使得设计更加复杂。
4. 装饰器模式(Decorator Pattern)

动态地给对象添加新的功能,而不改变其结构。

  • 使用场景:需要动态地为对象增加功能,如给窗体增加滚动条。
  • 优点:灵活性高,不改变原有类的情况下扩展功能。
  • 缺点:增加了系统的复杂性。
5. 外观模式(Facade Pattern)

提供一个统一的接口,来访问子系统中的一群接口,使得子系统更加容易使用。

  • 使用场景:当系统复杂,且需要对外提供简化的接口时。
  • 优点:简化了复杂系统的调用,降低了客户对子系统的依赖。
  • 缺点:可能掩盖了子系统的真正复杂性。
6. 享元模式(Flyweight Pattern)

通过共享已经存在的对象,减少创建对象的数量,从而减少内存开销。

  • 使用场景:大量相似对象存在,且内存占用大时,如文本编辑器中的字符对象。
  • 优点:减少内存消耗,提高性能。
  • 缺点:增加了系统复杂性。
7. 代理模式(Proxy Pattern)

为其他对象提供一种代理,以控制对这个对象的访问。

  • 使用场景:远程代理、虚拟代理、保护代理等场景。
  • 优点:控制访问权限,降低开销。
  • 缺点:引入了间接性,增加了复杂度。

三、行为型模式

行为型模式关注对象之间的通信和协作,目的是使对象之间的交互更加灵活。

1. 责任链模式(Chain of Responsibility Pattern)

将请求沿着处理链传递,直到有一个对象处理它。

  • 使用场景:需要多个对象处理请求,但处理者不确定时。
  • 优点:降低了请求发送者和接受者之间的耦合度。
  • 缺点:处理链过长时,性能可能受到影响。
2. 命令模式(Command Pattern)

将请求封装成对象,以便可以使用不同的请求、队列或日志来参数化其他对象。

  • 使用场景:实现撤销操作、事务管理等。
  • 优点:解耦请求发送者和接收者。
  • 缺点:增加了系统的复杂性。
3. 解释器模式(Interpreter Pattern)

给定一种语言,定义它的文法表示,并定义一个解释器来解释这些表达式。

  • 使用场景:编译器、规则引擎等。
  • 优点:灵活,易于扩展文法。
  • 缺点:文法复杂时,难以维护。
4. 迭代器模式(Iterator Pattern)

提供一种方法顺序访问一个集合对象中的各个元素,而不暴露其内部表示。

  • 使用场景:遍历集合对象时。
  • 优点:使得集合遍历统一。
  • 缺点:额外的开销。
5. 中介者模式(Mediator Pattern)

通过一个中介者对象来封装对象之间的交互,使得对象不需要显式地相互引用,降低了耦合度。

  • 使用场景:多个对象间交互复杂时,如GUI组件之间的通信。
  • 优点:减少了对象之间的依赖关系。
  • 缺点:中介者本身可能会变得复杂。
6. 备忘录模式(Memento Pattern)

在不破坏封装的前提下,捕获对象的内部状态,以便在未来可以恢复它。

  • 使用场景:实现撤销操作时。
  • 优点:实现了对象状态的快照。
  • 缺点:可能导致内存开销大。
7. 观察者模式(Observer Pattern)

定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。

  • 使用场景:事件监听机制,GUI框架等。
  • 优点:松散耦合,灵活性高。
  • 缺点:如果观察者太多,通知可能会导致性能问题。
8. 状态模式(State Pattern)

允许对象在其内部状态发生改变时改变其行为,看起来像是修改了它的类。

  • 使用场景:对象的行为随状态变化而变化时,如状态机。
  • 优点:将状态与行为封装在一个类中,减少条件语句。
  • 缺点:状态较多时,类的数量可能会增加。
9. 策略模式(Strategy Pattern)

定义一系列算法,并将它们封装起来,使它们可以互相替换,且算法的变化不会影响使用算法的客户。

  • 使用场景:当算法有多种实现方式
  • 优点:符合“开放-关闭”原则,易于扩展。
  • 缺点:客户端需要了解不同的策略类。
10. 模板方法模式(Template Method Pattern)

定义算法的骨架,并允许子类在不改变算法结构的情况下重新定义某些步骤。

  • 使用场景:固定算法流程,但部分步骤需要可扩展时。
  • 优点:复用代码,易于维护。
  • 缺点:灵活性受限。
11. 访问者模式(Visitor Pattern)

访问者模式用于将数据结构与操作解耦。通过在访问者中定义新的操作,可以避免修改数据结构。该模式允许你在不改变元素类的前提下,定义作用于这些类的新操作。

  • 使用场景:需要对一个对象结构中的元素执行许多不同的操作,但又不希望因为频繁增加新操作而修改这些类时。
    结构:访问者模式有两个关键角色:
  • 优点:增加新的操作非常简单,只需增加新的访问者类即可。符合单一职责原则,将不同操作的实现与对象结构的实现分离。
  • 缺点:如果对象结构经常改变,添加新元素会比较麻烦,因为所有的访问者类都需要更新。

这些设计模式是软件开发中常用的工具,通过合理的使用可以显著提高系统的灵活性、扩展性和可维护性。在实际开发中,选择合适的模式需要根据具体问题场景来判断。

参考文档
https://medium.com/nerd-for-tech/design-patterns-introduction-7022b8d384c6


http://www.ppmy.cn/embedded/128313.html

相关文章

中间件有哪些分类?

中间件的分类 中间件是位于操作系统和应用程序之间的软件,它提供了一系列服务来简化分布式系统中的应用程序开发和集成。中间件可以根据其功能和用途被分为不同的类别。以下是中间件的一些主要分类: 1. 通信处理(消息)中间件&am…

【vue+printJs】前端打印, 自定义字体大小, 自定义样式, 封装共享样式

效果示例 思维导图 目录 1,基本使用1, 依赖下载2, 页面导入3, 修改字体大小(可行但不推荐) 2, 自定义样式,字体大小1, 修改字体大小(推荐)2, 自定义样式3, 封装共享样式 3, 去除页面页脚内容4, 测试案例demo, 直接cv可用5, print-js的其他参数说明 1,基本使用 1, 依赖下载 …

systemd实现seatunnel自动化启停

在 systemd 中,您可以通过配置服务单元文件来设置服务在失败或退出后自动重启。这对于确保关键服务在意外退出时能够自动恢复运行非常有用。下面是实现 systemd 自动重启服务的步骤: 通用操作 1. 创建或编辑服务单元文件 假设服务单元文件位于 /etc/systemd/system/my-ser…

RTX3070的yolo训练模型迁移到NVIDIA JETSON XAVIER NX 上的踩坑经验,时机部署避雷点

NVIDIA JETSON XAVIER NX 的yolo环境部署 首先为了保证yolo的权重模型pt文件可以顺利迁移过去,要保证torch和cuda的版本一致 如何在NX上安装torch? 1.用 jtop工具 实时查看和控制板子状态 安装: sudo -H pip3 install jetson-stats使用: sudo jtop 在这里是为…

计算机网络基础(1)

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 计算机网络基础 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. 计算机网…

Vert.x,Web - Restful API

将通过Vert.x Web编写一个前后分离的Web应用,做为Vert.x Web学习小结。本文为后端部分,后端实现业务逻辑,并通过RESTfull接口给前端(Web页面)调用。 案例概述 假设我们要设计一个人力资源(HR)系统,要实现对员工信息的增删改查。…

C++笔记之静态多态和动态多态

C++笔记之静态多态和动态多态 code review! 在C++中,多态(Polymorphism)是面向对象编程的一个核心概念,允许对象以多种形式存在。多态性主要分为静态多态(Static Polymorphism)和动态多态(Dynamic Polymorphism)。下面将详细解释这两种多态及其在C++中的实现方式、优缺…

前端打印功能(vue +springboot)

后端 后端依赖生成pdf的方法pdf转图片使用(用的打印模版是带参数的 ,参数是aaa)总结 前端页面 效果 后端 依赖 依赖 一个是用模版生成对应的pdf,一个是用来将pdf转成图片需要的 <!--打印的--><dependency><groupId>net.sf.jasperreports</groupId>&l…