设计模式概览

设计模式是一种解决常见编程问题的经验总结,提供了代码的可重用性、可扩展性和可维护性。常见的设计模式有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.rhkb.cn/news/452935.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux多窗口调试一些常用命令

在 vim 或 neovim 中使用分屏移动光标的方式: 希望光标从左窗口移动到右侧窗口: 按 Ctrlw 然后按 l(小写的 L),光标就会从左边窗口移动到右边窗口。 其它分屏操作: Ctrlw h:移动到左边的窗…

【我的 RT 学习手札】信息收集

相关笔记整理自B站up主泷羽sec全栈渗透测试教学(免费) 视频链接为泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频 笔记只是方便师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线&#xff0…

11 图书借阅功能实现(Vue3+element plus +Spring Boot)

目录 1 功能描述2 接口地址3 后端代码4 api/book.js中编写借阅图书的接口代码5 BookResourcesVue.vue组件中完成点击事件borrowBook6 功能演示 1 功能描述 普通用户借阅图书,点击借阅按钮,修改图书状态,最多能够借阅3本图书。 2 接口地址 …

保证缓存一致性的常用套路

缓存更新的套路 看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。然而,这个是逻辑是错误的。试想,两个并发操作,一个是更新操作,另一个是…

[MyBatis-Plus]扩展功能详解

代码生成 使用MP的步骤是非常固定的几步操作 基于插件, 可以快速的生成基础性的代码 安装插件安装完成后重启IEDA连接数据库 mp是数据库的名字?serverTimezoneUTC 是修复mysql时区, 不加会报错 生成代码 TablePrefix选项是用于去除表名的前缀, 比如根据tb_user表生成实体类U…

恒定电流下有功率密度,功率密度体积分就是恒定电流的功率

体积趋于0时,体积的功率就叫功率密度 恒定电流的 电场乘距离等于电压 电流面密度*面积等于电流注意:电流面密度不是电荷线面体密度,电荷线面体密度用在静电场中,即电荷不运动这种

redo文件误删除后通过逻辑备份进行恢复

问题描述 开发同事让在一个服务器上查找下先前库的备份文件是否存在,如果存在进行下恢复。翻了服务器发现备份文件存在,多愁了一眼竟翻到了该备份文件于2024.6.17日恢复过的日志,赶紧和开发沟通说2024.6.17号已经恢复过了为啥还要恢复&#x…

ESP32_S3驱动舵机servor sg90

ESP32_S3驱动舵机servor sg90 硬件连接图硬件外观[^1]硬件引脚功能图硬件连接引脚对照表硬件接线图 Arduino IDE添加ESP32_S3开发板[^2]安装SERVO3舵机驱动库[^3]下载库ZIP包安装库 ESP32_S3程序下载方式源代码SERVO库自带例程方式二 参考文献 调试ESP32_S3舵机发现舵机不动。查…

多线程编程

使用多线程完成两个文件的拷贝&#xff0c;分支线程1&#xff0c;拷贝前一半&#xff0c;分支线程2拷贝后一半&#xff0c;主线程用于回收分支线程的资源 #include<myhead.h>typedef struct sockaddr_in addr_in_t; typedef struct sockaddr addr_t; typedef struct soc…

Redis --- 第四讲 --- 常用数据结构 --- Hash、List

一、Hash哈希类型的基本介绍。 哈希表&#xff1a;之前学过的所有数据结构中&#xff0c;最最重要的。 1、日常开发中&#xff0c;出场频率非常高。 2、面试中&#xff0c;非常重要的考点。 Redis自身已经是键值对结构了。Redis自身的键值对就是通过哈希的方式来组织的。把…

【MySQL 保姆级教学】数据类型全面讲解(5)

数据类型 1. 数据类型分类1.1 数值类型1.2 文本和二进制类型1.3 日期类型 2 数值类型2.1 TINYINT 类型2.1.1 默认有符号类型2.1.2 无符号类型 2.2 INT 类型2.2.1 默认有符号类型2.2.2 无符号类型 2.3 BIT 类型2.3.1 语法2.3.2 举例 2.4 FLOAT 类型2.4.1 语法2.4.2 默认有符号类…

OpenCV高级图形用户界面(20)更改窗口的标题函数setWindowTitle()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在OpenCV中&#xff0c;cv::setWindowTitle函数用于更改窗口的标题。这使得您可以在程序运行时动态地更改窗口的标题文本。 函数原型 void cv::…

keepalived(高可用)+nginx(负载均衡)+web

环境 注意&#xff1a; (1) 做高可用负载均衡至少需要四台服务器&#xff1a;两台独立的高可用负载均衡器&#xff0c;两台web服务器做集群 (2) vip&#xff08;虚拟ip&#xff09;不能和物理ip冲突 (3) vip&#xff08;虚拟ip&#xff09;最好设置成和内网ip同一网段&#xf…

【Vulnhub靶场】Kioptrix Level 3

目标 本机IP&#xff1a;192.168.118.128 目标IP&#xff1a;192.168.118.0/24 信息收集 常规 nmap 扫存活主机&#xff0c;扫端口 根据靶机IP容易得出靶机IP为 192.168.118.133 nmap -sP 192.168.118.0/24nmap -p- 192.168.118.133 Getshell 开放22端口和80 端口 访问web…

Git极速入门

git初始化 git -v git config --global user.name "" git config --global user.email "" git config --global credential.helper store git config --global --list省略(Local) 本地配置&#xff0c;只对本地仓库有效–global 全局配置&#xff0c;所有…

第十七周:机器学习笔记

第十七周周报 摘要Abstratc一、机器学习——生成式对抗网络&#xff08;Generative Adversarial Networks | GAN&#xff09;——&#xff08;中&#xff09;1. GAN 的理论介绍2. 用JS散度训练存在的问题3. WGAN 算法4. 拓展——流体 总结 摘要 本周周报主要对GAN进行了详细的…

在ESP-IDF环境中如何进行多文件中的数据流转-FreeRTOS实时操作系统_流缓存区“xMessageBuffer”

一、建立三个源文件和对应的头文件 建立文件名&#xff0c;如图所示 图 1-1 二、包含相应的头文件 main.h 图 2-1 mess_send.h mess_rece.h和这个中类似,不明白的大家看我最后面的源码分享 图2-2 三、声明消息缓存区的句柄 大家注意&#xff0c;在main.c中定义的是全局变…

免费字体二次贩卖;刮刮乐模拟器;小报童 | 生活周刊 #4

Raycast 的两款在线工具 Raycast 公司出品&#xff0c;必属精品&#xff0c;之前的代码转图片工具&#xff0c;交互和颜值都做得很漂亮 现在又新出了一个 图标制作器&#xff0c;一键制作美观好看的图标 猫啃网 没想到像【汇文明朝体】这样免费的字体都被人拿来当成【打字机字…

基于知识图谱的电子元器件问答系统

你还在为寻找电子元器件的相关信息头疼吗&#xff1f;作为一名程序员或电子工程师&#xff0c;在项目中经常需要快速查询电子元件的属性或关联关系。今天给大家介绍一个可以大大提升工作效率的神器——基于知识图谱的电子元器件问答系统。这不仅是你学习和工作的好帮手&#xf…

vue2使用pdfjs-dist实现pdf预览(iframe形式,不修改pdfjs原来的ui和控件,dom层可以用display去掉一部分组件)

前情提要 在一开始要使用pdf预览的时候&#xff0c;第一次选的是vue-pdf&#xff0c;但是vue-pdf支持的功能太少&#xff0c;缺少了项目中需要的一项-复制粘贴功能 之后我一顿搜搜搜&#xff0c;最终貌似只有pdfjs能用 但是网上支持text-layer的貌似都是用的2.09那个版本。 使…