当前位置: 首页 > 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上的个人热点…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...