设计模式原理

目录

设计模式原则

 一、抽象工厂模式

1.1 定义

1.2 类图

1.3 优点

1.4 例子

二、单例模式

2.1 定义

2.2 优缺点

2.3 应用场景

Runtime.java

DefaultSingletonBeanRegistry.java

ReactiveAdapterRegistry.java

Currency.java

2.4 实现方式

1、懒汉模式

2、恶汉模式

3、静态内部类

反射打破单例模式情况


设计模式原则

开闭原则 对扩展开放,对修改关闭

单⼀职责原则 ⼀个类只负责⼀个功能领域中的相应职责

⾥⽒替换原则 所有引⽤基类的地⽅必须能透明地使⽤其⼦类的对象

依赖倒置原则 依赖于抽象,不能依赖于具体实现

接⼝隔离原则 类之间的依赖关系应该建⽴在最⼩的接⼝上

合成/聚合复⽤原则 尽量使⽤合成/聚合,⽽不是通过继承达到复⽤的⽬的

迪⽶特法则 ⼀个软件实体应当尽可能少的与其他实体发⽣相互作⽤

 一、抽象工厂模式

1.1 定义

抽象工厂模式(Abstract FactoryPattern)围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂

1.2 类图

1.3 优点

单一职责

开闭原则 

1.4 例子

Connection.java

二、单例模式

2.1 定义

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

2.2 优缺点

优点:一个单例类只存在一个实例,减少开销、避免创建和销毁是对资源的多重占用

确定:没有抽象层、难以扩展、违反设计模式思想的单一职责原则。

2.3 应用场景

线程池、连接池等情况

Runtime.java

标准的恶汉模式

DefaultSingletonBeanRegistry.java

懒汉模式

ReactiveAdapterRegistry.java

volatile的懒汉模式

Currency.java

带序列化和反序列化

2.4 实现方式

1、懒汉模式

需要优化:线程安全、双重校验、防止指令重排 voilatile

为什么要用voilatile?

因为可见性、防止指令重排,new过程不是原子操作。会经历1、开启堆空间 2、构造方法初始化对象 3、引用变量指向堆内存空间

package com.example.demo.designPattern.singleton;

/**
 * @author 10450
 * @description 懒汉模式
 * 并发情况下,有可能
 * @date 2022/9/15 13:58
 */
public class LazySingletonTest {
    public static void main(String[] args){
        new Thread(()->{
            LazySingleton intance = LazySingleton.getSingleton();
            System.out.println(intance);
        }).start();

        new Thread(()->{
            LazySingleton intance = LazySingleton.getSingleton();
            System.out.println(intance);
        }).start();

        new Thread(()->{
            LazySafeSingleton intance = LazySafeSingleton.getSingleton();
            System.out.println(intance);
        }).start();

        new Thread(()->{
            LazySafeSingleton intance = LazySafeSingleton.getSingleton();
            System.out.println(intance);
        }).start();

        new Thread(()->{
            LazyVolatileSingleton intance = LazyVolatileSingleton.getSingleton();
            System.out.println(intance);
        }).start();

        new Thread(()->{
            LazyVolatileSingleton intance = LazyVolatileSingleton.getSingleton();
            System.out.println(intance);
        }).start();
    }
}

/**
 * 多线程不安全
 */
class LazySingleton{
    private static LazySingleton instance;
    private LazySingleton(){
    }
    public static LazySingleton getSingleton(){
        if(instance==null){
            try{
                Thread.sleep(5000);
                instance =  new LazySingleton();
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return instance;
    }
}
/**
 * 多线程安全,但是指令重排有问题
 */
class LazySafeSingleton{
    private static LazySafeSingleton instance;
    private LazySafeSingleton(){
    }
    public static LazySafeSingleton getSingleton(){
        if(instance==null){
            synchronized (LazySafeSingleton.class){
                if(instance==null){
                    try{
                        Thread.sleep(5000);
                        instance =  new LazySafeSingleton();
                    }catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return instance;
    }
}

/**
 * 防止指令重排
 */
class LazyVolatileSingleton{
    private volatile static LazyVolatileSingleton instance;
    private LazyVolatileSingleton(){
    }
    public static LazyVolatileSingleton getSingleton(){
        if(instance==null){
            synchronized (LazyVolatileSingleton.class){
                if(instance==null){
                    try{
                        Thread.sleep(5000);
                        instance =  new LazyVolatileSingleton();
                    }catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return instance;
    }
}



2、恶汉模式

类加载的初始化节点完成实例初始化。本质就是JVM类加载机制,保证实例唯一性。

类加载是就创建对象、比较常用,但是容易浪费空间。

优点:线程安全、没有加锁,执行效率快

缺点:浪费空间

类加载过程:

  1. 加载二进制字节码数据到内存中,生成对应class数据结构
  2. 连接:a:验证、b:准备(给类的静态成员变量赋默认值),c:解析
  3. 初始化:给类静态变量赋初值
  4. package com.example.demo.designPattern.singleton;
    
    /**
     * @author 10450
     * @description 恶汉模式
     * 类加载的时候完成初始化
     * @date 2022/9/15 14:23
     */
    public class HungrySingletonTest {
        public static void main(String[] args) {
            System.out.println(HungrySingleton.getInstance());
            System.out.println(HungrySingleton.getInstance());
        }
    }
    
    class HungrySingleton{
        private static HungrySingleton  instance = new HungrySingleton();
        private HungrySingleton(){
        }
        public static HungrySingleton getInstance(){
            return instance;
        }
    }

    3、静态内部类

     优点:懒加载,线程安全,效率较⾼,实现简单

  • 本质上利用类的加载机制保证线程安全
  • 只要在实际使用的时候才会触发累的初始化,也是懒加载的一种
  • package com.example.demo.designPattern.singleton;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    
    /**
     * @author 10450
     * @description 静态内部类
     * 可以防止通过反射,实现多利
     * @date 2022/9/15 14:28
     */
    public class InnerClassSingletonTest {
        public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            new Thread(()->{
                System.out.println(InnerClassSingleton.getInstance());
            }).start();
    
            new Thread(()->{
                System.out.println(InnerClassSingleton.getInstance());
            }).start();
            
            //利用反射方式创建类对象打破单例模式,实现多利
            Constructor<InnerClassSingleton> declaredConstructor = InnerClassSingleton.class.getDeclaredConstructor();
            declaredConstructor.setAccessible(true);
            InnerClassSingleton innerClassSingleton = declaredConstructor.newInstance();
            InnerClassSingleton instance = InnerClassSingleton.getInstance();
            System.out.println(innerClassSingleton);
            System.out.println(instance);
        }
    }
    
    class InnerClassSingleton{
        private static class InnerClassSingletonHolder{
            private static InnerClassSingleton instance = new InnerClassSingleton();
        }
        private InnerClassSingleton(){
        }
        public static InnerClassSingleton getInstance(){
            try {
                System.out.println(1);
                Thread.sleep(8000);
                System.out.println(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return InnerClassSingletonHolder.instance;
        }
    }
    

    反射打破单例模式情况

通过反射方式创建类,可以打破单例模式,实现多例效果,

【恶汉模式】、【内部类模式】可以判断防止多例

package com.example.demo.designPattern.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author 10450
 * @description 反射攻击
 * @date 2022/9/15 15:03
 */
public class InnerClassReflexSingletonTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //单例保护防止多利情况下:
        Constructor<InnerClassProtectSingleton> declaredConstructor = InnerClassProtectSingleton.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        InnerClassProtectSingleton innerClassSingleton = declaredConstructor.newInstance();
        InnerClassProtectSingleton instance = InnerClassProtectSingleton.getInstance();
        System.out.println(innerClassSingleton);
        System.out.println(instance);
    }
}

/**
 * 防止多例
 */
class InnerClassProtectSingleton {
    private static class InnerClassSingletonHolder {
        private static InnerClassProtectSingleton instance = new InnerClassProtectSingleton();
    }

    private InnerClassProtectSingleton() {
        //添加校验,抛异常
        if (InnerClassSingletonHolder.instance != null) {
            throw new RuntimeException("单例模式,不运行重复创建");
        }
    }

    public static InnerClassProtectSingleton getInstance() {
        return InnerClassProtectSingleton.InnerClassSingletonHolder.instance;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值