设计模式笔记(一)

目录

设计模式共有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)的方法

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值