当前位置: 首页 > news >正文

详解23种设计模式优缺点以及解决方案

1. 单例模式(Singleton Pattern):

  • 优点:确保一个类只有一个实例,提供全局访问点,节省资源。
  • 缺点:可能引入全局状态,难以扩展和测试。
  • 解决方法:使用依赖注入来替代直接访问单例对象,以便更好地控制依赖关系和测试。

2. 工厂模式(Factory Pattern):

  • 优点:封装对象的创建,客户端代码与具体类解耦。
  • 缺点:增加了代码复杂性,需要额外的工厂类。
  • 解决方法:使用抽象工厂模式,将具体工厂的创建抽象化,提供更高层次的抽象。

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

  • 优点:提供一种创建相关对象家族的接口,客户端代码与具体类解耦。
  • 缺点:增加了代码复杂性,难以支持新类型的产品。
  • 解决方法:使用依赖注入和反射机制来动态创建产品实例,增加灵活性。

4. 建造者模式(Builder Pattern):

  • 优点:将构建复杂对象的过程与其表示分离,灵活性高,易于扩展。
  • 缺点:增加了代码量,需要定义多个类。
  • 解决方法:使用流畅接口(Fluent Interface)来简化构建过程,提供更好的可读性。

5. 适配器模式(Adapter Pattern):

  • 优点:将不兼容的接口转换为客户端所期望的接口,提供了接口的转换和重用。
  • 缺点:增加了代码复杂性,需要创建适配器类。
  • 解决方法:使用接口适配器模式,减少适配器类的数量,使用默认适配方法。

6. 桥接模式(Bridge Pattern):

  • 优点:将抽象部分与实现部分解耦,可以独立地进行扩展。
  • 缺点:增加了代码复杂性,需要定义多个类。
  • 解决方法:使用组合和依赖注入来替代继承,使得抽象和实现可以独立变化。

7. 组合模式(Composite Pattern):

  • 优点:将对象组合成树形结构,统一处理单个对象和对象集合。
  • 缺点:限制了组合对象的类型,可能导致设计过度。
  • 解决方法:使用接口来定义组合对象,灵活处理不同类型的组合对象。

8. 装饰器模式(Decorator Pattern):

  • 优点:动态地给对象添加额外的职责,避免使用子类进行扩展。
  • 缺点:增加了代码复杂性,可能导致过多的装饰器层级。
  • 解决方法:使用透明装饰器模式,确保装饰器和被装饰对象具有相同的接口。

9. 外观模式(Facade Pattern):

  • 优点:提供了一个简化的接口,隐藏了系统的复杂性。
  • 缺点:可能会违背单一职责原则,导致外观对象过于庞大。
  • 解决方法:合理划分外观的职责,遵循单一职责原则,将复杂任务委派给其他对象。

10. 享元模式(Flyweight Pattern):

  • 优点:共享细粒度对象,减少内存使用和提高性能。
  • 缺点:增加了代码复杂性,需要维护共享对象的状态。
  • 解决方法:使用对象池来管理共享对象,避免手动维护共享对象的状态。

11. 代理模式(Proxy Pattern):

  • 优点:为其他对象提供一种代理,控制对对象的访问。
  • 缺点:增加了代码复杂性,可能会降低性能。
  • 解决方法:使用动态代理来延迟对象的创建和方法的执行,提高灵活性和性能。

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

  • 优点:将请求的发送者和接收者解耦,通过链式传递请求。
  • 缺点:可能导致请求的处理链过长,难以调试和定位错误。
  • 解决方法:合理划分责任链的职责,避免过长的链条,增加错误处理机制。

13. 命令模式(Command Pattern):

  • 优点:将请求封装成对象,使得可以用不同的请求对客户进行参数化。
  • 缺点:可能导致命令类的膨胀,增加了代码复杂性。
  • 解决方法:使用函数式接口和Lambda表达式来简化命令对象的创建和使用。

14. 解释器模式(Interpreter Pattern):

  • 优点:定义了一种语言的文法表示,并提供解释器来解释语言中的表达式。
  • 缺点:增加了代码复杂性,难以扩展和维护。
  • 解决方法:使用现有的解释器框架和工具来简化解释器的实现。

15. 迭代器模式(Iterator Pattern):

  • 优点:提供一种方法顺序访问聚合对象中的元素,而不暴露其内部表示。
  • 缺点:增加了代码复杂性,需要实现迭代器接口。
  • 解决方法:使用Java 8引入的Stream API来简化集合的遍历和操作。

16. 中介者模式(Mediator Pattern):

  • 优点:用一个中介对象来封装一系列对象之间的交互,减少对象之间的直接依赖。
  • 缺点:增加了代码复杂性,中介者对象可能会变得庞大。
  • 解决方法:将中介者对象拆分成多个小的中介者对象,提高灵活性和可维护性。

17. 备忘录模式(Memento Pattern):

  • 优点:在不破坏封装的前提下,捕获并保存对象的内部状态,以便后续恢复。
  • 缺点:增加了代码复杂性,可能会占用大量内存。
  • 解决方法:使用序列化和持久化技术来保存和恢复对象的状态,减少内存占用。

18. 观察者模式(Observer Pattern):

  • 优点:定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
  • 缺点:可能导致观察者对象过多,难以维护。
  • 解决方法:使用现有的观察者框架和库来简化观察者的实现和管理。

19. 状态模式(State Pattern):

  • 优点:允许对象在其内部状态改变时改变其行为,使得状态转换更加明确和可控。
  • 缺点:增加了代码复杂性,需要定义多个状态
  • 解决方案:
    • 使用状态模式需要根据实际情况进行权衡和设计,避免状态类过多和过于复杂。
    • 可以使用享元模式来共享相同状态的对象,减少对象的数量。
    • 可以使用策略模式来替代某些简单的状态,减少状态类的数量。

20. 策略模式(Strategy Pattern):

  • 优点:定义了一系列算法,并将每个算法封装到独立的类中,使得它们可以互相替换。提供了灵活的算法选择和扩展性。
  • 缺点:客户端需要了解不同的策略类,增加了代码的复杂性。
  • 解决方法:使用工厂模式创建策略对象,并通过依赖注入将策略对象传递给客户端。

21. 模板方法模式(Template Method Pattern):

  • 优点:定义了一个算法的框架,将具体步骤延迟到子类中实现。提供了一种代码复用和扩展的方式。
  • 缺点:子类的扩展可能会影响算法的整体结构。
  • 解决方法:使用钩子方法来允许子类影响算法的执行过程,提供更大的灵活性。

22. 访问者模式(Visitor Pattern):

  • 优点:将数据结构和对数据的操作分离,使得可以在不改变数据结构的前提下定义新的操作。
  • 缺点:增加了代码复杂性,需要在数据结构中添加访问者接受方法。
  • 解决方法:使用反射机制来动态调用访问者的方法,减少对数据结构的侵入性。

23. 职责链模式(Chain of Responsibility Pattern):

  • 优点:将请求的发送者和接收者解耦,动态地组织处理链。
  • 缺点:可能导致请求的处理链过长,难以调试和定位错误。
  • 解决方法:合理划分责任链的职责,增加错误处理机制,例如添加默认处理器或者抛出异常来处理未匹配的请求。

相关文章:

详解23种设计模式优缺点以及解决方案

1. 单例模式(Singleton Pattern): 优点:确保一个类只有一个实例,提供全局访问点,节省资源。缺点:可能引入全局状态,难以扩展和测试。解决方法:使用依赖注入来替代直接访…...

Oracle 数据库中删除表空间的详细步骤与示例

系列文章目录 文章目录 系列文章目录前言一、查看表空间二、数据迁移和备份三、下线表空间中的对象四、删除表空间五、删除完成后的操作总结前言 在 Oracle 数据库中,表空间是存储数据的逻辑容器。有时候,我们可能需要删除不再使用的表空间以释放空间或进行数据库重组。本文…...

<kernel>kernel 6.4 笔记

<kernel>kernel 6.4 笔记 1、kernel 与用户层通信过程 (1) kernel 通过uevent事件 通知 用户层; 第一步:准备同事事件的参数键值对存到环境变量中; 第二步 :准备环境变量数据 ACTION、DEVPATH、SUBSYSTEM…...

介绍一些编程语言— Perl 语言

介绍一些编程语言— Perl 语言 Perl 语言 简介 Perl 是一种动态解释型的脚本语言。 最初的设计者为拉里・沃尔,它于 1987 1987 1987 年 12 12 12 月 18 18 18 日发表。Perl 借取了 C、sed、awk、shell scripting 以及很多其他编程语言的特性。其中最重要的特性…...

原型与继承

原型与继承 在 JavaScript 中,对象有一个特殊的隐藏属性 [[Prototype]](如规范中所命名的),它要么为 null,要么就是对另一个对象的引用。该对象被称为“原型。 当我们从 object 中读取一个缺失的属性时,Jav…...

Flink流批一体计算(14):PyFlink Tabel API之SQL查询

举个例子 查询 source 表,同时执行计算 # 通过 Table API 创建一张表: source_table table_env.from_path("datagen") # 或者通过 SQL 查询语句创建一张表: source_table table_env.sql_query("SELECT * FROM datagen&quo…...

JRebel插件扩展-mac版

前言 上一篇分享了mac开发环境的搭建,但是欠了博友几个优化的债,今天先还一个,那就是idea里jRebel插件的扩展。 一、场景回眸 这个如果在win环境那扩展是分分钟,一个exe文件点点就行。现在在mac环境就没有这样的dmg可以执行的&…...

C语言中常见的一些语法概念和功能

常用代码: 程序入口:int main() 函数用于定义程序的入口点。 输出:使用 printf() 函数可以在控制台打印输出。 输入:使用 scanf() 函数可以接收用户的输入。 条件判断:使用 if-else 语句可以根据条件执行不同的代码…...

Python土力学与基础工程计算.PDF-钻探泥浆制备

Python 求解代码如下: 1. rho1 2.5 # 黏土密度,单位:t/m 2. rho2 1.0 # 泥浆密度,单位:t/m 3. rho3 1.0 # 水的密度,单位:t/m 4. V 1.0 # 泥浆容积,单位:…...

【机器学习】— 2 图神经网络GNN

一、说明 在本文中,我们探讨了图神经网络(GNN)在推荐系统中的潜力,强调了它们相对于传统矩阵完成方法的优势。GNN为利用图论来改进推荐系统提供了一个强大的框架。在本文中,我们将在推荐系统的背景下概述图论和图神经网…...

QT的布局与间隔器介绍

布局与间隔器 1、概述 QT中使用绝对定位的布局方式,无法适用窗口的变化,但是,也可以通过尺寸策略来进行 调整,使得 可以适用窗口变化。 布局管理器作用最主要用来在qt设计师中进行控件的排列,另外,布局管理…...

深入浅出Pytorch函数——torch.nn.Linear

分类目录:《深入浅出Pytorch函数》总目录 对输入数据做线性变换 y x A T b yxA^Tb yxATb 语法 torch.nn.Linear(in_features, out_features, biasTrue, deviceNone, dtypeNone)参数 in_features:[int] 每个输入样本的大小out_features :…...

Vue3.2+TS的defineExpose的应用

defineExpose通俗来讲,其实就是讲子组件的方法或者数据,暴露给父组件进行使用,这样对组件的封装使用,有很大的帮助,那么defineExpose应该如何使用,下面我来用一些实际的代码,带大家快速学会defi…...

牛客网Python入门103题练习|【08--元组】

⭐NP62 运动会双人项目 描述 牛客运动会上有一项双人项目,因为报名成功以后双人成员不允许被修改,因此请使用元组(tuple)进行记录。先输入两个人的名字,请输出他们报名成功以后的元组。 输入描述: 第一…...

Jenkins改造—nginx配置鉴权

先kill掉8082的端口进程 netstat -natp | grep 8082 kill 10256 1、下载nginx nginx安装 EPEL 仓库中有 Nginx 的安装包。如果你还没有安装过 EPEL,可以通过运行下面的命令来完成安装 sudo yum install epel-release 输入以下命令来安装 Nginx sudo yum inst…...

(二)VisionOS平台概述

2.VisionOS平台概述 1. VisionOS平台概述 Unity 对VisionOS的支持将 Unity 编辑器和运行时引擎的全部功能与RealityKit提供的渲染功能结合起来。Unity 的核心功能(包括脚本、物理、动画混合、AI、场景管理等)无需修改即可支持。这允许游戏和应用程序逻…...

菜单中的类似iOS中开关的样式

背景是我们有需求,做类似ios中开关的按钮。github上有一些开源项目,比如 SwitchButton, 但是这个项目中提供了很多选项,并且实际使用中会出现一些奇怪的问题。 我调整了下代码,把无关的功能都给删了,保留核…...

Vue 2 动态组件和异步组件

先阅读 【Vue 2 组件基础】中的初步了解动态组件。 动态组件与keep-alive 我们知道动态组件使用is属性和component标签结合来切换不同组件。 下面给出一个示例&#xff1a; <!DOCTYPE html> <html><head><title>Vue 动态组件</title><scri…...

MongoDB升级经历(4.0.23至5.0.19)

MongoDB从4.0.23至5.0.19升级经历 引子&#xff1a;为了解决MongoDB的两个漏洞决定把MongoDB升级至最新版本&#xff0c;期间也踩了不少坑&#xff0c;在这里分享出来供大家学习与避坑~ 1、MongoDB的两个漏洞 漏洞1&#xff1a;MongoDB Server 安全漏洞(CVE-2021-20330) 漏洞2…...

iPhone上的个人热点丢失了怎么办?如何修复iPhone上不见的个人热点?

个人热点功能可将我们的iPhone手机转变为 Wi-Fi 热点&#xff0c;有了Wi-Fi 热点后就可以与附近的其他设备共享其互联网连接。 一般情况下&#xff0c;个人热点打开就可以使用&#xff0c;但也有部分用户在升级系统或越狱后发现 iPhone 的个人热点消失了。 iPhone上的个人热点…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...