23种设计模式(持续输出中)

一.设计模式的作用

设计模式是软件从业人员长期总结出来用于解决特定问题的通用性框架,它提高了代码的可维护性、可扩展性、可读性以及复用性。

二.设计模式
1.工厂模式

工厂模式提供了创建对象的接口,而无需制定创建对象的具体类,工厂类封装了具体类的创建过程,客户端无需知道具体实现类只需要知道工厂类,通过工厂类来创建具体实现的类。

1).优缺点
优点:

(1).松耦合:无需知道子类具体创建过程,只需要关注工厂类。
(2).可扩展性:扩展性高,如果想增加一个产品,只需要增加子类对应的工厂类即可。

缺点:

每增加一个产品,就需要增加一个具体的类和对应的工厂类,可维护性并不高,增加了代码复杂性。

2).应用场景

使用数据库连接工厂类连接不同的数据库,比如达梦、崖山等

3).类图

在这里插入图片描述

4).具体实现过程

(1).创建一个接口
在这里插入图片描述
(2).创建实体类
在这里插入图片描述

在这里插入图片描述

(3).创建工厂类
在这里插入图片描述
(4).根据类型调用工厂类连接数据库
在这里插入图片描述

2.抽象工厂模式

抽象工厂模式是围绕一个超级工厂创建其他工厂,此超级工厂又称为其他工厂的工厂,抽象工厂模式提供了一个接口,通过此接口及其具体实现类,可以将对象的创建与客户端代码分离,从而实现系统的松耦合。

1).优缺点
优点:

(1).保证产品族一致性:抽象工厂模式创建的产品族类都是同一类产品,客户端使用此族类的产品的时候也都是使用此族类的产品。
(2).实现松耦合:客户端代码只需要通过抽象工厂接口创建产品无需知道产品具体实现代码。
(3).有利于扩展:增加新的产品族类,只需要添加新的具体工厂和产品类即可。

缺点:

每次增加产品族类都要添加一个此族类的工厂代码,还要添加此工厂的具体实现代码,系统和代码复杂性变高。

2).应用场景

比如格力和美的电器都会生产很多产品,空调、洗衣机、冰箱、热水器等,这些都是产品族类。

3).组成

抽象工厂:一般为接口,声明了创建产品对象的方法;
具体工厂:实现了抽象工厂,用于创建产品对象的具体类;
抽象产品:一般为接口或抽象类,声明实现产品的公共方法,具体产品必须要实现此方法;
具体产品:实现了抽象产品;

4).类图

在这里插入图片描述

5).具体实现

(1).创建一个接口
在这里插入图片描述
在这里插入图片描述
(2).创建接口的实体类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3).创建抽象工厂类
在这里插入图片描述

(4).创建抽象工厂类的扩展实现类
在这里插入图片描述
在这里插入图片描述
(5).创建生成器
在这里插入图片描述
(5).使用
在这里插入图片描述

3.单例模式

单例模式确保一个类只有一个实例,单例模式还需要提供一个全局访问方法

1).优缺点
优点:

(1).避免一个全局使用的类频繁地创建与销毁
(2).保证了全局状态的一致性

缺点:

(1).过度使用单例可能导致全局状态不可控

2).应用场景

获取打印机去打印图纸,可以使用单例模式去创建打印机;IP访问次数计数等;

3).具体实现
public class Singleton {//实例私有private static Singleton instance;//构造方法私有private Singleton() {}//创建实例的方法公开,如果没创建就创建实例,如果创建了就不在创建public static Singleton getInstance() {if (instance == null) {// 如果实例为空,则创建一个新实例instance = new Singleton();}return instance;}
}
4.建造者模式

建造者模式提供了一种允许用户逐步设置各种属性来构建对象的方式,很多参数对于一个对象来说可能是可选的,开发者无需传递所有参数去创建对象,对于可选的参数如果用户未传就要去除,所以我们就可以将构建复杂组件的步骤与运用组件构建对象分离,使用builder模式建立。

1).优缺点
优点:

(1).分离构建过程和表示,使得构建过程更加灵活
(2).隐藏具体构建细节,提高封装性
(3).提供代码复用性

缺点:

(1).增加代码复杂性,对于步骤简单的对象没必要使用此模式

2).应用场景

需要生成的对象具有复杂的内部结构,创建者创建对象的步骤和参数过多而且需要更加灵活

3).具体实现

比如一个用户,姓名、电话、性别是必选的,但是住址、年龄、邮箱是可选的,有些用户可能输入年龄,有些用户可能给了地址等;这里通过UserBuilder去实现根据不同的参数创建User对象;
(1).创建User类和UserBuilder类型

public class User {//名称 必填private String name;//性别 必填private String sex;//电话 必填private String phone;//年龄 可选private Integer age;//住址 可选private String address;//住址 可选private String email;public User(UserBuilder userBuilder) {this.name = userBuilder.name;this.sex = userBuilder.sex;this.phone = userBuilder.phone;this.age = userBuilder.age;this.address = userBuilder.address;this.email = userBuilder.email;}public static UserBuilder builder(String name, String sex, String phone){return new UserBuilder(name,sex,phone);}public static class UserBuilder {//名称private String name;//性别private String sex;//电话private String phone;//年龄private Integer age;//住址private String address;//住址private String email;//构造器public UserBuilder(String name, String sex, String phone) {this.name = name;this.sex = sex;this.phone = phone;}public UserBuilder age(Integer age) {this.age = age;return this;}public UserBuilder address(String address) {this.address = address;return this;}public UserBuilder email(String email) {this.email = email;return this;}public User build(){return new User(this);}}
}

(2).使用UserBuilder创建user
在这里插入图片描述

5.原型模式

原型模式通过复制现有对象来创建新对象,也就是拷贝现有的实例对象来创建对象,而不需重头创建对象。

1).优缺点
优点:

(1).提高创建对象的效率,减少创建对象成本
(2).无需知道构造函数内部逻辑,降低了耦合度

缺点:

(1).对于对象内部的引用有循环接口或者对象内部有不支持序列化的引用对象就不支持拷贝

2).应用场景

当类初始化比较复杂、比较耗时耗性能、需要获取权限等的时候需要使用原型模式

3).深拷贝和浅拷贝

(1).浅拷贝:拷贝一个对象后,基本数据类型的变量会重新创建,引用类型指向的还是原对象所指向的
(2).深拷贝:拷贝一个对象后,基本数据类型还有引用对象都是重新创建的,比如clone方法就是深拷贝

4).具体实现

(1).实体类继承Cloneable ,复写clone方法

public class User implements Cloneable {//名称 必填private String name;//性别 必填private String sex;//电话 必填private String phone;//年龄 可选private Integer age;//住址 可选private String address;//住址 可选private String email;@Overridepublic User clone() {try {return (User) super.clone();} catch (CloneNotSupportedException e) {return null;}}

(2).使用
在这里插入图片描述

6.适配器模式

通过一个适配器类将一个接口转换成另一个接口,使得两个不兼容的对象能够协同工作,从而消除不兼容问题

1).优缺点
优点:

(1).将不同的系统、库、组件适配在一起,而无需修改太多的代码,提高代码的复用性
(2).拥有更高的灵活性

缺点:

(1).过多的适配器会导致代码混乱降低维护性

2).类图

Mp4PlayerImpl专门用于播放MP4文件,Mp3PlayerImpl专门用于播放MP3,如果Mp4PlayerImpl想播放MP3文件那么就需要一个适配器Mp4PlayerAdapter去适配Mp3PlayerImpl的接口,去代理播放MP3文件。

在这里插入图片描述

3).具体实现

(1).实现MP4播放功能
在这里插入图片描述
在这里插入图片描述
(2).实现MP3播放功能
在这里插入图片描述
在这里插入图片描述
(3).实现MP4的适配器

在这里插入图片描述

(4).使用
在这里插入图片描述

7.策略模式

根据条件(比如操作类型)而选择不同的行为或者算法,这就是策略模式,如果将不同的行为代码硬编写在一起会非常臃肿同时也不利于拓展。

1).优缺点
优点:

(1).算法可以根据条件选择
(2).利于拓展
(3).可以将公共方法抽出放在父类中,提高代码复用性

缺点:

(1).每个行为或者算法都要有一个类,这导致类的增加,导致测量膨胀
(2).所有策略类都要对外暴露,不太安全

2).应用场景

需要根据条件去选择不同的行为,比如高速公路显示屏可以根据不同指令选择播放语音、播放文字、还是点亮警报灯

3).类图

抽象类OperateHander有三个子类LineOperateHander、MusicOperateHander、PlayOperateHander,通过适配器器OperateManager根据类型去判断使用不同的Hander
在这里插入图片描述

4).具体实现

(1).编写Hander
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

(2).编写枚举

@Getter
@AllArgsConstructor
public enum OperateType {LINE_OPERATE("line", "lineOperateHander"),MUSIC_OPERATE("music", "musicOperateHander"),PLAY_OPERATE("play", "playOperateHander"),;private final String type;private final String handler;public static OperateType getByType(String type) {OperateType[] types = values();for (OperateType syncType : types) {if (syncType.getType().equals(type)) {return syncType;}}return null;}
}

(3).编写适配器
在这里插入图片描述

8.模版模式

模板方法模式通过定义一个抽象的父类,其中包含了流程中公共的行为,子类去实现流程中非公共的行为,这样就可以保证核心流程保持不变,同时增加了代码的复用性

1).优缺点
优点:

(1).增加代码复用性
(2).所有子类共享父类的代码,保证代码一致性
(3).利于维护

缺点:

(1).每一个非公共的行为都要增加一个子类,增加了子类的数量

2).应用场景

请假的流程和请病假的流程基本一致,都需要发起流程、主管审批、经理审批,但是请假发起流程的时候需要输入请假理由、请假天数等,但是请病假需要申请理由、请假天数、还需要医院症断书等,我们将公共部分的流程(发起、主管审批、经理审批)抽到父类,具体的差别子类去实现

3).类图

在这里插入图片描述

4).具体实现

(1).编写模版代码
在这里插入图片描述
(2).编写请假代码
在这里插入图片描述
(3).编写请病假代码
在这里插入图片描述

9.观察者模式

观察者模式定义了一种一对多的依赖关系,一个被观察者(主题)对应多个观察者,被观察者发生改变时候会通知所有观察者。观察者实现了与观察者之间的解耦。

1).优缺点
优点:

(1).观察者和被观察者是解耦合的。
(2).主题状态改变时会自动通知观察者,减少手动维护通知的工作

缺点:

(1).异步操作可能无法保证顺序一致性
(2).可能存在循环依赖的问题

2).业务场景

老师发布放假信息,所有的学生都会收到通知

3).具体实现
(1).编写观察者代码
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7e42afad03f542cda88f0c00d3fc71b9.png)

在这里插入图片描述
在这里插入图片描述
(2).编写主题代码
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/331345.html

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

相关文章

HarmonyOS之ArkUI布局设计常见细节

这里写目录标题 1. Button设置带有渐变色的背景图片无效1.1 问题分析1.2 成功案例 2. 路由跳转失败2.1 问题分析 1. Button设置带有渐变色的背景图片无效 1.1 问题分析 说明:设置颜色渐变需先设置backgroundColor为透明色。 Button($r(app.string.login), { type…

【机器学习】机器学习与大型预训练模型的前沿探索:跨模态理解与生成的新纪元

🔒文章目录: 💥1.引言 ☔2.跨模态理解与生成技术概述 🚲3.大型预训练模型在跨模态理解与生成中的应用 🛴4.前沿探索与挑战并存 👊5.未来趋势与展望 💥1.引言 近年来,机器学习领…

解决Flutter位于悬浮窗口时,应用Logo不更新问题

问题描述 我已经更换了应用Logo,但是发现应用处于悬浮窗口时,logo还是更改之前的?下面的图片只是示意。 解决方案 终端命令 rm -rf ~/Library/Developer/Xcode/DerivedData2.xcode视图内解决 先在顶部找到 Xcode --> Setting --> Lo…

代码随想录算法训练营第十七天(py)| 二叉树 | 513.找树左下角的值、112. 路径总和、106.从中序与后序遍历序列构造二叉树

513.找树左下角的值 力扣链接 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 思路 层序遍历 层序遍历之后,取最后一个数组的第一个元素 class Solution:def findBottomLeftValue(self, root: Optional[TreeNode]) -> …

深入解析编程逻辑中的关键字与逻辑运算

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、认识关键字及其重要性 二、逻辑运算的关键字 1. and、or 和 not 的运用 2. 逻辑运算的…

世界上首位AI程序员诞生,AI将成为人类的对手吗?

3月13日,世界上第一位AI程序员Devin诞生,不仅能自主学习新技术,自己改Bug,甚至还能训练和微调自己的AI模型,表现已然远超GPT-4等“顶流选手”。 AI的学习速度如此之快,人类的教育能否跟上“机器学习”的速…

【C++算法】BFS解决单源最短路问题相关经典算法题

1.迷宫中离入口最近的出口 首先我们可以将这道题目简化一下,可以往我们这一章的主题上面来想想。 我们利层序遍历来解决最短路径问题,是最经典的做法。我们可以从起点开始层序遍历, 并组在遍历的过程中记录当前遍历的层数。这样就能在找到出口的时候&…

人工智能应用-实验7-胶囊网络分类minst手写数据集

文章目录 🧡🧡实验内容🧡🧡🧡🧡代码🧡🧡🧡🧡分析结果🧡🧡🧡🧡实验总结🧡🧡 &#x1f9…

缓存IO与直接IO

IO类型 缓存 I/O 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间(用户空间&#xff0…

常见 JVM 面试题补充

原文地址 : 26 福利:常见 JVM 面试题补充 (lianglianglee.com) CMS 是老年代垃圾回收器? 初步印象是,但实际上不是。根据 CMS 的各个收集过程,它其实是一个涉及年轻代和老年代的综合性垃圾回收器。在很多文章和书籍的划分中&…

Hive运行错误

Hive 文章目录 Hive错误日志错误SessionHiveMetaStoreClientql.Driver: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTaskerror: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster Please check …

三、自定义信号和槽函数(无参和有参)

需求: 下班后,小明说请小红吃好吃的,随便吃,吃啥买啥 无参:小红没有提出吃啥 有参:小红提出自己想吃的东西,吃啥取决于一时兴起(emit触发) 思路: 1&#xff…

【高时效通路】

一 高时效通路 1.1 pathchdumper 实时数据拉取、实时数据处理、5分钟微批dump来加速时效性,具体来说: 实时数据拉取(Fetcher):基于Databus Fetcher基建,直接对接F0层实时拉取最新数据,保证该…

电脑键盘如何练习盲打?

电脑键盘如何练习盲打?盲打很简单,跟着我做,今天教会你。 请看【图1】: 【图1】中,红色方框就是8个基准键位,打字时我们左右手的8个手指就是放在这8个基准键位上,F键和J键上各有一个小突起&…

AcW木棒-XMUOJ恢复破碎的符咒木牌-DFS与剪枝

题目 思路 话不多说,直接上代码 代码 /* AcW木棒-XMUOJ恢复破碎的符咒木牌 搜索顺序:从小到大枚举最终的长度 len从前往后依次拼每根长度为len的木棍 优化: 1.优化搜索顺序:优先选择深度短的来搜索,故从大到小去枚…

Java——简易图书管理系统

本文使用 Java 实现一个简易图书管理系统 一、思路 简易图书管理系统说白了其实就是 用户 与 图书 这两个对象之间的交互 书的属性有 书名 作者 类型 价格 借阅状态 而用户可以分为 普通用户 管理员 使用数组将书统一管理起来 用户对这个数组进行操作 普通用户可以进…

Python简介

Python简介 1. Python定义 Python 是一种简单易学并且结合了解释性、编译性、互动性和面向对象的脚本语言。Python提供了高级数据结构,它的语法和动态类型以及解释性使它成为广大开发者的首选编程语言。 Python 是解释型语言: 开发过程中没有了编译这个环…

Android Gradle开发、应用、插件发布(六)—实现打包自动复制文件插件

1. 前言 项目中遇到了一个问题 : 其中一个模块MyLibrary的assets文件夹中,需要存放很多文件(每个文件对应一个功能)。 这样导致的问题是MyLibrary打出的这个aar包体积特别大。 如果把MyLibrary严谨地拆解成若干个Module又比较费时,对于现在业务现状来…

Vue3实战笔记(42)—Vue + ECharts:流量数据可视化的强大组合

文章目录 前言vue3使用echarts标准demo:总结 前言 在前端开发中,数据可视化已经成为了一个不可或缺的部分。Vue.js作为一个轻量级且易于上手的渐进式JavaScript框架,与ECharts这个强大的数据可视化库的结合,使得在Vue应用中构建交…

Mysql插入中文内容报错解决及其Mysql常用的存储引擎说明

一、问题描述 我们在Mysql数据库的表中插入带有中文内容时报错,提示【1366 - Incorrect string value: \xE5\x8C\x97\xE4\xBA\xAC... for column UserDealer at row 1】,如下图所示: 二、问题分析 一般来说插入中文内容有问题我们首先想到的就是编码问题;我们可以查看该表使…