设计模式笔记(一)

news2024/11/17 16:22:29

目录

设计模式共有23种,也可称为GOF23

单例模式(重点,常用)

工厂模式

代理模式:(SpringAOP的底层原理)

静态代理模式:(写死一个代理类Proxy)

动态代理模式(基于接口:jdk动态代理;基于类:cglib动态代理):


Java设计模式是一套在Java程序设计中经过反复使用、多数人知晓的、代码设计经验的总结。它提供了一种框架和结构,旨在帮助开发者更好地理解和设计复杂的系统。设计模式不仅仅是一种语法规则,更是一种思想和方法论,能够帮助开发者更好地分析、设计和实现软件系统,确保代码的重用性、可维护性和可扩展性。这些模式通常被分为创建型模式、结构型模式和行为型模式,每种模式都针对特定的设计问题提供了标准的解决方案。

设计模式共有23种,也可称为GOF23

 下面我分次来介绍几种常见的设计模式:

单例模式(重点,常用)

饿汉式:(一上来就把对象加载啦,可能会浪费内存空间)

大致包括:私有的构造器;static final 且 私有 的new对象; public的访问器 返回对象;

(new对象时的static是因为静态方法里只能调用静态属性,final修饰类属性是防止二次改变指向)

懒汉式:(用的时候才加载对象)

(懒汉式有很多 :多线程不安全的懒汉式,多线程安全的懒汉式(性能不够高),双重检测锁的懒汉式(多线程安全+高性能))

双重检测锁懒汉式:

私有构造器; volatile锁防止指令重排序 保证原子性操作;双重检验锁 ,保证高性能

多线程、高并发场景下更加安全

 详细解析:

public class Singleton {  
    private volatile static Singleton singleton;  //私有属性无法直接读到,
    //这个volatile防止指令重排序,第一个线程创建成功但是未完全转为非空,第六个以后的线程会进入第一个if语句,会很麻烦
    private Singleton (){}  //构造方法私有  是防止new新对象
    
    //每个线程通过这个公有方法来获取对象,相当于一个访问器
    public static Singleton getSingleton() { 
     //这里必须是静态方法,防止能new出来对象(与单例模式相矛盾)
     //静态方法中操作变量也必须是静态的(故上面的唯一变量对象是静态的),否则不能在这个静态方法中调用它
     //(因为静态方法里面无法操作全局的非静态变量)
    if (singleton == null) { //第一次假设5个线程通过了这条if语句,当这5个执行完之后,6、7、8个再进来时会被这个if语句拦截,直接return最初创建的新对象
     //多线程调用的情况下,如果是空的话,先锁起来,只允许一个线程创建对象,否则多线程同时拷贝调用这个方法,就创建了多个对象
        synchronized (Singleton.class) {  //多线程竞争这个锁,进来的只有一个,其余竞争失败线程进入阻塞队列
            if (singleton == null) { //第一个线程创建完对象后,singleton 不为空,第一个阻塞队列中的线程(假设2、3、4、5线程)再进来时被这条if语句拦截,故不能再次创建,此时可以直接return一个对象(第一个线程创建的)
                singleton = new Singleton();  
            }   // 进来的第一个线程成功创建了对象,然后执行完毕释放锁;原阻塞队列的其他线程再来竞争第一个锁
        }  
    }  
    return singleton;  
    }  
}

工厂模式

作用:创建者和调用者分离

核心本质:

  • 实例化对象不使用new,用工厂方法代替
  • 将选择实现类,创建对象的统一管理和控制。从而将调用者跟我们的实现类解耦。

常见工厂模式:

简单工厂模式

使用一个单独的工厂类来创建不同的对象,根据传入的参数判断创建哪种类型的对象。

工厂方法模式:每个人都有自己的工厂(工厂类变多)

定义了一个创建对象的(工厂)接口,但由子类决定实例化哪个类(需要哪个就实例化哪个实现类)。

代理模式:(SpringAOP的底层原理)

静态代理模式:(写死一个代理类Proxy)

最终还是要new一个固定的代理类,直接面向代理类来操作

动态代理模式(基于接口:jdk动态代理;基于类:cglib动态代理):

可以动态生成代理类,不把代理类写死,只写一个代理角色(动态生成代理类)

大致过程:

首先有原接口userService和原接口实现类userServiceImpl;

然后有一个类(实现InvocationHandler接口)可以自动生成代理类。在这个类里面:

1、加上被代理的接口,并实现set方法

2、新建一个方法体 return一个 Proxy.newProxyInstance(三个参数);

三个参数分别为:类加载,代理的哪个接口,this(InvocationHandler的实现类)

这个方法体的作用:得到代理类

3、实现InvocationHandler接口的invoke方法,处理代理的实例,并返回结果(这里是反射的知识)三个参数:调用方法的对象实例,要调用的方法的名称,实际传递给方法的参数值

再来一个类:

new一个真实的最原来的类,例:userServiceImpl

new一个代理角色(上一步创建的那个类)假设名字为pih

pih.set方法(要代理的对象,传入的是接口)

pih.getProxy();动态生成代理类,用proxy来接收

proxy.query(); 用代理类来调用原来类(userServiceImpl)的方法

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

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

相关文章

【Java版数据结构】初识泛型

看到这句话的时候证明:此刻你我都在努力 加油陌生人 br />个人主页:Gu Gu Study专栏:Java版数据结构 喜欢的一句话: 常常会回顾努力的自己,所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1…

学习笔记:MySQL数据库操作5

1. 触发器(Triggers) 触发器是数据库的一种高级功能,它允许在执行特定数据库操作(如INSERT、UPDATE、DELETE)之前或之后自动执行一段代码。 1.1 创建商品和订单表 商品表(goods) gid: 商品编号…

navicat15安装破解

下载地址: 链接:https://pan.baidu.com/s/19RlXTArDfNxT5n98A0GbvQ 提取码:qtew 破解教程 1、运行注册机,勾选Backup、Host和Navicat v15,如图所示。然后点击Patch按钮,找到Navicat Premium 15安装路径下的…

什么是模型无关方法?

「AI秘籍」系列课程: 人工智能应用数学基础人工智能Python基础人工智能基础核心知识人工智能BI核心知识人工智能CV核心知识AI 进阶:企业项目实战 可直接在橱窗里购买,或者到文末领取优惠后购买: 可以与任何模型一起使用的所有强…

破局产品同质化:解锁3D交互式营销新纪元!

近年来,随着数字体验经济的蓬勃发展,3D交互式营销作为一种创新手段迅速崛起,它巧妙地解决了传统产品展示中普遍存在的缺乏差异性和互动性的问题,使您的产品在激烈的市场竞争中独树一帜,脱颖而出。 若您正面临产品营销…

抖音直播弹幕数据逆向:websocket和JS注入

🔍 思路与步骤详解 🕵️‍♂️ 思路介绍 首先,我们通过抓包工具进入的直播间,捕获其网络通信数据,重点关注WebSocket连接。发现直播弹幕数据通过WebSocket传输,这种方式比传统的HTTP更适合实时数据的传输。…

昇思25天学习打卡营第24天 | Pix2Pix实现图像转换

昇思25天学习打卡营第24天 | Pix2Pix实现图像转换 文章目录 昇思25天学习打卡营第24天 | Pix2Pix实现图像转换Pix2Pix模型cGANCGAN的损失函数 数据网络构建生成器判别器Pix2Pix网络 总结打卡 Pix2Pix模型 Pix2Pix是基于条件生成对抗网络(cGAN, Condition Generativ…

如何在测试中保护用户隐私!

在当今数据驱动的时代,用户隐私保护成为了企业和开发团队关注的焦点。在软件测试过程中,处理真实用户数据时保护隐私尤为重要。本文将介绍如何在测试中保护用户隐私,并提供具体的方案和实战演练。 用户隐私保护的重要性 用户隐私保护不仅是法…

Qt自定义带前后缀图标的PushButton

写在前面 Qt提供QPushButton不满足带前后缀图标的需求,因此考虑自定义实现带前后缀图标的PushButton,方便后续快速使用。 效果如下: 同时可设置前后缀图标和文本之间间隙: 代码实现 通过前文介绍的Qt样式表底层实现 可以得…

linux ftp操作记录

一.ftp 创建用户 passwd: user ftpuser does not exist 如果你遇到 passwd: user ftpuser does not exist 的错误,这意味着系统中不存在名为 ftpuser 的用户。你需要首先确认FTP用户是否是系统用户,还是FTP服务器软件(如Pure-FTPd&#xff…

类和对象:完结

1.再深构造函数 • 之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅ 式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成 员列表&#xf…

redis的使用场景

1. redis的使用场景 redis使用场景的案例:[1]热点数据的缓存[2]分布式锁[3]短信业务(登录注册时)2. redis实现注册登录功能 代码 在发送验证码时,先判断数据库是否有该手机号,有则发送验证码(此时redis缓存…

基于微信小程序+SpringBoot+Vue的自习室选座与门禁系统(带1w+文档)

基于微信小程序SpringBootVue的自习室选座与门禁系统(带1w文档) 基于微信小程序SpringBootVue的自习室选座与门禁系统(带1w文档) 本课题研究的研学自习室选座与门禁系统让用户在小程序端查看座位,预定座位,支付座位价格,该系统让用户预定座位…

Jmeter三种方式获取数组中多个数据并将其当做下个接口参数入参【附带JSON提取器和CSV格式化】

目录 一、传统方式-JOSN提取器获取接口返回值 1、接口调用获取返回值 2、添加JSON提取器 3、调试程序查看结果 4、添加循环控制器 5、设置count计数器 6、添加请求 7、执行请求 二、CSV参数化 1、将结果写入后置处理程序 2、设置循环处理器 3、添加CSV文件 4、设置…

【机器学习】用Jupyter Notebook实现并探索单变量线性回归的代价函数以及遇到的一些问题

引言 在机器学习中,代价函数(Cost Function)是一个用于衡量模型预测值与实际值之间差异的函数。在监督学习中,代价函数是评估模型性能的关键工具,它可以帮助我们了解模型在训练数据上的表现,并通过优化过程…

IPD推行成功的核心要素(十五)项目管理提升IPD相关项目交付效率和用户体验

研发项目往往包含很多复杂的流程和具体的细节。因此,一套完整且标准的研发项目管理制度和流程对项目的推进至关重要。研发项目管理是成功推动创新和技术发展的关键因素。然而在实际管理中,研发项目管理常常面临着需求不确定、技术风险、人员素质、成本和…

PyTorch安装CUDA标准流程(可解决大部分GPU无法使用问题)

最近一段时间在研究PyTorch中的GPU的使用方法,之前曾经安装过CUDA,不过在PyTorch中调用CUDA时无法使用。考虑到是版本不兼容问题,卸载后尝试了其他的版本,依旧没有能解决问题,指导查阅了很多资料后才找到了解决方案。 …

uni-app声生命周期

应用的生命周期函数在App.vue页面 onLaunch:当uni-app初始化完成时触发(全局触发一次) onShow:当uni-app启动,或从后台进入前台时显示 onHide:当uni-app从前台进入后台 onError:当uni-app报错时触发,异常信息为err 页面的生命周期 onLoad…

数据治理之“财务一张表”

前言 信息技术的发展,伴随企业业务系统的纷纷建设,提升业务处理效率的同时,也将企业的整体主价值链流程分成了一段一段的业务子流程,很多情况下存在数据上报延迟、业务协作不顺畅、计划反馈不及时、库存积压占资多……都可以从数据…

20240725java的Controller、DAO、DO、Mapper、Service层、反射、AOP注解等内容的学习

在Java开发中,‌controller、‌dao、‌do、‌mapper等概念通常与MVC(‌Model-View-Controller)‌架构和分层设计相关。‌这些概念各自承担着不同的职责,‌共同协作以构建和运行一个应用程序。‌以下是这些概念的解释:‌…