Java设计模式(23种设计模式 重点介绍一些常用的)

news2024/11/27 15:47:18
  • 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
  • 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

设计模式原则

开放封闭原则

就是对扩展开放,对原有类的修改封闭。在不影响原有类的基础上进行拓展

里氏代换原则

子类型必须能够替换父类型,也就是父类型的功能可以被复用。

单一职责原则

一个类仅应该有一个引起他变化的原因。可拓展性高。

依赖倒置原则

高层模块和底层模块都应该依赖于抽象,细节应该依赖于抽象。

比如电脑内存条坏了,我们仅仅需要更换内存条就行了,而不需要把cpu也换了,类似于一种解藕的思想。

迪米特法则

如果两个类不必直接通信,则可以通过一个第三者去转发调用。降低耦合度。

合成复用原则

原则是尽量使用合成/聚合的方式,而不是使用继承。

常用的模式

简单工厂模式

拿经典的加减乘除来举例

  1. 我们需要先封装一个算法抽象类,定义方法。
  2. 然后定义加减乘除四个子类继承该抽象类,并实现
  3. 最后在创建一个算法工厂类,通过switch(运算符)来实现对应的算法。

抽象工厂模式

比如封装一个多数据源的访问。

  1. 新建一个接口,定义访问的方法。
  2. 然后各个数据库为其创建对应的类,实现该接口。
  3. 再定义一个工厂接口,实现对应对象创建的方法。
  4. 再定义几个类去实现该接口的方法。
  5. 可以实例化对应的工厂去使用。

工厂方法模式

还是拿经典的加减乘除来举例

  1. 我们需要先封装一个算法抽象类,定义方法。
  2. 然后定义加减乘除四个子类继承该抽象类,并实现
  3. 最后在创建一个工厂接口。
  4. 定义多种算法工厂类实现该接口,例如将基础算法归于一类,高级算法归于一类。
  5. 最后再拿一个算法工厂类通过switch(运算符)去实现对应的算法。

抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
将工厂抽象成两层,抽象工厂 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂集合, 更利于代码的维护和扩展。

 

装饰者模式

动态的给类添加一些额外的职责,就添加功能来说,该模式比生成子类更加灵活。

  1. 定义一个抽象类component
  2. concretecomponent类继承抽象类
  3. decorator继承了component的抽象类,可以从外部扩展component功能
  4. 定义具体装饰类继承decorator
  • Component(抽象构件):定义一个对象接口,以规范准备接收附加责任的对象。
  • ConcreteComponent(具体构件):实现Component接口,也就是给装饰者提供原始对象。
  • Decorator(抽象装饰者):实现Component接口,持有对另一个Component对象的引用,并定义一个与Component接口一致的接口。
  • ConcreteDecorator(具体装饰者):实现Decorator接口,给组件添加一些职责。

 

策略者模式

定义了算法策略,分别封装起来,让他们可以互相替换,不会影响到使用算法的客户。

  1. 定义一个算法抽象类
  2. 几个具体实现类
  3. 定义一个conext类,内部使用算法抽象类,实例化,并调用其的算法
  • 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
  • 上下文(Context)类:是使用算法的角色, 持有一个策略类的引用,最终给客户端调用。

 

 

模板模式(很简单)

定义一个算法骨架,将一些步骤延迟到子类中,使得子类不需要改变算法结构就可以重新定义某个步骤

  1. 一个抽象类
  2. 几个实现类

代理模式

为其他对象提供一种代理以控制该对象的访问

  1. 定义一个抽象类或接口
  2. 定义一个具体实现类继承该类
  3. 再定义一个具体代理类,并在内部将上一个具体类作为成员变量

动态代理与静态代理的区别就是代理类与被代理类有没有直接继承或实现的关系。 

 

【设计模式】Java 的三种代理模式_创建代理对象的三大方式-CSDN博客 

责任链模式

使多个对象都有机会去处理请求,从而避免请求的发送者和接收者的关系之前的耦合。将对象链接成一个链,并通过该链条传递该请求,直到有一个对象处理他。

  1. 定义一个父接口
  2. 实现多个子类,可以实现不同内容处理
  3. 通过链条方式将他们链接起来
  4. 先从底层开始处理

java设计模式---责任链模式详解_责任链模式 java-CSDN博客 

 Java设计模式-责任链模式_java责任链模式-CSDN博客

单例模式

保证一个类只有一个实例,并且提供一个访问他的全局访问点。

  • 将类成员变量设置为静态
  • 私有化其他构造方法,只留一个构造,且内部进行判断,如果已经实例化,则直接返回。
  • 且在成员变量加volatile关键字
  • 实例化成员变量时内部加上synchronized锁,防止并发创建多个实例。
  • 或者采用静态初始化

 代码示例

class Singleton{
    private static Singleton instance = new Singleton();
    private Singleton(){
    }
    public static Singleton getInstance(){
        return instance;
    }
 }
或者
class Singleton{
    private volatile static Singleton instance = new Singleton();
    private Singleton(){
    }
    public static Singleton getInstance(){
        if(instance==null){
            synchornized(Singleton.class){
                if(instance==null){
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
 }

创建型模式

工厂方法模式

与简单工厂方法比较类似,在简单工厂基础上进行了二次封装,让各类的职责更加明确。

还是拿经典的加减乘除来举例

  1. 我们需要先封装一个算法抽象类,定义方法。
  2. 然后定义加减乘除四个子类继承该抽象类,并实现
  3. 最后在创建一个工厂接口。
  4. 定义多种算法工厂类实现该接口,例如将基础算法归于一类,高级算法归于一类。
  5. 最后再拿一个算法工厂类通过switch(运算符)去实现对应的算法。

抽象工厂模式

比如封装一个多数据源的访问。

  1. 新建一个接口,定义访问的方法。
  2. 然后各个数据库为其创建对应的类,实现该接口。
  3. 再定义一个工厂接口,实现对应对象创建的方法。
  4. 再定义几个类去实现该接口的方法。
  5. 可以实例化对应的工厂去使用。

单例模式

保证一个类只有一个实例,并且提供一个访问他的全局访问点。

  • 将类成员变量设置为静态
  • 私有化其他构造方法,只留一个构造,且内部进行判断,如果已经实例化,则直接返回。
  • 且在成员变量加volatile关键字
  • 实例化成员变量时内部加上synchronized锁,防止并发创建多个实例。
  • 或者采用静态初始化
class Singleton{
    private static Singleton instance = new Singleton();
    private Singleton(){
    }
    public static Singleton getInstance(){
        return instance;
    }
 }
或者
class Singleton{
    private volatile static Singleton instance = new Singleton();
    private Singleton(){
    }
    public static Singleton getInstance(){
        if(instance==null){
            synchornized(Singleton.class){
                if(instance==null){
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
 }

建造者模式

将一个复杂对象的构建和他的表示分离,同样的建造过程可以创建不同的表示

比如产品类

  1. 先写一个抽象建造者类,把抽象方法都定义好
  2. 然后写几个具体建造者类继承抽象类
  3. 然后指导者类,内部构造去写一个调用抽象类的创建人的各个方法。

可以实现客户并不知道具体的建造过程

原型模式

用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

  1. 封装一个抽象类实现cloneable接口,重写clone方法。
  2. 创建具体原型类继承抽象类

结构型模式

适配器模式

将一个类的接口转换为客户需要的另一个接口。该模式使原本接口不兼容而不能一起工作的类可以一起工作。

  1. 首先定义两个接口
  2. 然后定义一个适配器类继承并重写其中方法,并且定义另一个类作为变量,在重写方法中用到。

装饰器模式

动态的给类添加一些额外的职责,就添加功能来说,该模式比生成子类更加灵活。

  1. 定义一个抽象类component
  2. concretecomponent类继承抽象类
  3. decorator继承了component的抽象类,可以从外部扩展component功能
  4. 定义具体装饰类继承decorator

代理模式

为其他对象提供一种代理以控制该对象的访问

  1. 定义一个抽象类或接口
  2. 定义一个具体实现类继承该类
  3. 再定义一个具体代理类,并在内部将上一个具体类作为成员变量

外观模式

为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,该接口使得该子系统更加容易使用。

  1. 定义四个子系统类
  2. 定义一个外观类,将四个子系统类全部实例化并写方法。

桥接模式

将抽象部分和实现部分相分离,使得他们可以独立的变化

  1. 定义一个抽象类
  2. 几个具体实现类
  3. 另一个抽象类 内部依赖第一个抽象类
  4. 具体类继承该抽象类

组合模式

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

  1. 定义一个component
  2. 定义两个子类leaf和composite

享元模式

运用共享技术有效的支持大量细粒度的对象

  1. 定义一个抽象类,几个具体类
  2. 再定义一个抽象工厂,内部依赖抽象类

行为型模式

策略模式

定义了算法策略,分别封装起来,让他们可以互相替换,不会影响到使用算法的客户。

  1. 定义一个算法抽象类
  2. 几个具体实现类
  3. 定义一个conext类,内部使用算法抽象类,实例化,并调用其的算法

模板方法模式

定义一个算法骨架,将一些步骤延迟到子类中,使得子类不需要改变算法结构就可以重新定义某个步骤

  1. 一个抽象类
  2. 几个实现类

观察者模式

定义了一种一堆多的关系,让多个观察者同时监听某个对象,该对象发生变化,会通知观察者对象去更新自己。

  1. 定义通知者抽象类接口,内部使用了观察者类
  2. 定义具体通知者
  3. 定义观察者抽象类接口,内部有更新方法
  4. 几个具体观察者类

迭代子模式

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

  1. 定义一个聚合抽象类
  2. 具体实现类
  3. 定义一个iterator迭代器抽象类
  4. 再定义一个具体类
  5. 就可以实现使用该迭代器去遍历具体聚合类

责任链模式

使多个对象都有机会去处理请求,从而避免请求的发送者和接收者的关系之前的耦合。将对象链接成一个链,并通过该链条传递该请求,直到有一个对象处理他。

  1. 定义一个父接口
  2. 实现多个子类,可以实现不同内容处理
  3. 通过链条方式将他们链接起来
  4. 先从底层开始处理

命令模式

将请求封装为对象,用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持撤销的操作。

  1. 定义一个命令接口,内部调用一个接收者类
  2. 定义接收者
  3. 定义具体命令类
  4. 定义invoker类,内部调用命令类
  5. 实例化接收者,实例化命令
  6. 实例化invoker,执行方法。

备忘录模式

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存该状态,这样以后就可将该对象恢复到原先保存的状态。

  • 发起人 调用备忘录
  • 备忘录
  • 管理类 管理备忘录

状态模式

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类

  • 状态抽象类
  • 几个具体状态类
  • 一个上下文类

访问者模式

表示一个作用于某对象的元素的操作,他可以使在不改变元素情况下定义作用与这些元素的新操作

  • 访问者
  • 元素类
  • 对象结构类

中介者模式

用一个中介来封装交互的动作。

  1. 定义一个抽象人 内部含中介
  2. 再定义两个具体人
  3. 然后定义一个中介
  4. 定义几个具体中介
  5. 通过实例化中介和人,给人设置相同中介就可以交互

解释器模式

给一个语言,定义他的一种表示,并定义一个解释器,用于解释

  • 上下文类
  • 抽象表达类
  • 具体实现

推荐书籍:大话设计模式,清华出版社的,写的真的很不错!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot整合SpringSecurit,实现ajax的登录、退出、权限校验

1、本文章中SpringBoot整合SpringSecurity&#xff0c;只是基于session方式&#xff0c;并且没有使用到redis。 2、登录、登出都是通过ajax的方式进行。 项目目录&#xff1a; 1、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xm…

Leecode热题100---二分查找---搜索插入位置

题目&#xff1a; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 nums 为 无重复元素 的 升序 排列数组 常规思路&#xff1a; class Solution { public:int f…

走进全球LED显示龙头艾比森,深挖逆势增长43%的数智化逻辑

在大环境不景气的情况下&#xff0c;有一家智能制造企业在2023年营收40亿&#xff0c;同比增长高达43%&#xff0c;海外营收增长约 46%&#xff0c;并且连续12年单品牌出口额第一。 这就是全球LED显示龙头艾比森。 5月9日&#xff0c;纷享销客带领近70位企业高管走进纷享销客…

设计模式 22 访问者模式 Visitor Pattern

设计模式 22 访问者模式 Visitor Pattern 1.定义 访问者模式是一种行为型设计模式&#xff0c;它允许你在不改变已有类结构的情况下&#xff0c;为一组对象添加新的操作。它将算法与对象结构分离&#xff0c;使你能够在不修改现有类的情况下&#xff0c;为这些类添加新的操作。…

922. 按奇偶排序数组 II - 力扣

1. 题目 给定一个非负整数数组 nums&#xff0c; nums 中一半整数是 奇数 &#xff0c;一半整数是 偶数 。 对数组进行排序&#xff0c;以便当 nums[i] 为奇数时&#xff0c;i 也是 奇数 &#xff1b;当 nums[i] 为偶数时&#xff0c; i 也是 偶数 。 你可以返回 任何满足上述…

大学生简历写作指南:让你的简历脱颖而出

在求职过程中&#xff0c;简历不仅是展示自己的镜子&#xff0c;更是赢得面试机会的敲门砖。本文将从简历排版、专业简历定制、内容筛选等方面&#xff0c;提供全面的指导&#xff0c;帮助打造一份既有深度又接地气的简历。 一、简历排版 1.1 根据岗位要求调整排版 准备简历…

LeetCode215数组中第K个最大元素

题目描述 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 解析 快速排序的思想&#xff…

【机器学习】【深度学习】批量归一化(Batch Normalization)

概念简介 归一化指的是将数据缩放到一个固定范围内&#xff0c;通常是 [0, 1]&#xff0c;而标准化是使得数据符合标准正态分布。归一化的作用是使不同特征具有相同的尺度&#xff0c;从而使模型训练更加稳定和快速&#xff0c;尤其是对于使用梯度下降法的算法。而标准化的作用…

Pytorch环境配置2.0.1+ Cuda11.7

查找cuda、cudnn、Pytorch(GPU)及cuda和NVIDIA显卡驱动对应关系 查询可支持的最高cuda版本 nvidia-smi查看支持的cuda的版本 CUDA版本对应表 我的显卡驱动是Driver Version&#xff1a;535.40.&#xff0c;那么左边对应的CUDA都可以兼容 右上角为CUDA 版本&#xff0c;可以看…

OTFS系统建模、通信性能分析、信道估计、模糊函数【附MATLAB代码】

文献来源&#xff1a;​微信公众号&#xff1a;EW Frontier OTFS简介 OTFS信道估计 % Clear command window, workspace variables, and close all figures clc; clear all; close all; ​ % Define Eb values in dB EbdB -10:2:10; ​ % Convert Eb values from dB to lin…

【计算机毕业设计】基于SSM++jsp的汽车客运站管理系统【源码+lw+部署文档】

目录 第1章 绪论 1.1 课题背景 1.2 课题意义 1.3 研究内容 第2章 开发环境与技术 2.1 MYSQL数据库 2.2 JSP技术 2.3 SSM框架 第3章 系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 系统流程 3.2.1 操作流程 3.2.2 登录流程 3.2.3 删除信息流…

【iOS】didReceiveMemoryWarning实例方法

iPhone下每个App可用的内存是被限制的&#xff0c;如果一个App使用的内存超过20M&#xff0c;则系统会向该App发送Memory Warning&#xff08;内存警告&#xff09;消息&#xff0c;收到此消息后&#xff0c;App必须正确处理&#xff0c;否则可能出错或出现内存泄漏。 目录 流程…

查询DQL

016条件查询之等量关系 条件查询语法格式 select ... from... where过滤条件;等于 select empno, ename from emp where sal3000;select job, sal from emp where enameFORD;select grade, losal, hisal from salgrade where grade 1;不等于 <> 或 ! selectempno,en…

JS逆向之企名科技

文章目录 初步分析定位js编写完整代码参考文献初步分析 目标网址:企名科技 抓包分析,发现是post请求 请求代码如下: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import requestsheaders = {Connection:

MySQL 数据类型和搜索引擎

文章目录 【 1. 数据类型 】1.1 数值类型1.1.1 整型1.1.2 小数1.1.3 数值类型的选择 1.2 日期和时间YEAR 年TIME 时间DATE 日期DATETIME 日期时间TIMESTAMP 时间戳日期和时间的选择 1.3 文本字符串CHAR 固定字符串、VARCHAR 可变字符串TEXT 文本ENUM 枚举SET 集合字符串类型的选…

错误提示:“由于找不到steam_api.dll,无法继续执行代码”修复方法,缺少steam_api.dll文件原因

在尝试运行某些游戏或程序时&#xff0c;用户可能会遇到一个常见的错误提示&#xff1a;“由于找不到steam_api.dll&#xff0c;无法继续执行代码”。这个错误信息表明&#xff0c;系统在启动程序或游戏时无法定位到必要的steam_api.dll文件&#xff0c;这是一个关键的动态链接…

SwiftUI初探

SwiftUI 虽然出现了好几年(1.0好像2019年出的&#xff0c;还有SPM也是同一年)&#xff0c;现在已经到从1.0到5.0&#xff0c;但受限于对系统的要求(最低iOS13.0,有的要求17.0及以上)&#xff0c;每个版本里面差异也很大&#xff0c;语法和Flutter 的Dart 比较像。空闲之余可以先…

黑马es0-1实现自动补全功能

1、安装分词器 上github上找人做好的分词器&#xff0c;放到es-plugin数据卷里&#xff0c;然后重启es即可 2、自定义分词器 elasticsearch中分词器(analyzer)的组成包含三部分: character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符 …

【Python编程实战】基于Python语言实现学生信息管理系统

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

若依ruoyi-vue element-ui 横向滚动条 动态横向滚动条

动态横向滚动条 因为每次横向滑动都要到底部&#xff0c;引入插件 https://github.com/mizuka-wu/el-table-horizontal-scroll //动态横向滚动条移入样式 .el-table-horizontal-scrollbar :hover{//高度 变大10%transform: scaleY(1.5) translateY(-10%);//百分之八十亮度&a…