[toc]

手写单例模式

饿汉模式

public class Singleton {
 
    private static final Singleton instance = new Singleton();
 
    private Singleton() {
    }
 
    public static Singleton getInstance() {
        return instance;
    }
 
}
 

优点是线程安全的,只有一个实例。缺点是即使没有调用getInstance()方法,instance实例在类加载时被初始化了。

双重检查锁模式,非线程安全

public class Singleton {
 
    private static Singleton instance;
 
    private Singleton() {
    }
 
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
 
}

静态内部类

public class Singleton {
 
    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }
 
    private Singleton() {
    }
 
    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

装饰器模式

代理模式 (静态、动态)

静态代理:需要代理对象和目标对象实现一样的接口。 缺点:

  1. 冗余。由于代理对象要实现与目标对象一致的接口,会产生过多的代理类。
  2. 不易维护。一旦接口增加方法,目标对象与代理对象都要进行修改。

动态代理: 动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。

静态代理与动态代理的区别主要在:

  • 静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件
  • 动态代理是在运行时动态生成的,即编译完成后没有实际的 class 文件,而是在运行时动态生成类字节码,并加载到 JVM中

JDK 动态代理和 cglib 代理: 1、Jdk 动态代理:利用拦截器(必须实现 InvocationHandler 接口)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用 InvokeHandler 来处理 2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来进行代理

cglib 与 JDK 动态代理最大的区别就是

  • 使用动态代理的对象必须实现一个或多个接口
  • 使用 cglib 代理的对象则无需实现接口,达到代理类无侵入。

工厂模式

适配器模式

策略模式

Java 库、中间件等用了哪些设计模式

oop - Examples of GoF Design Patterns in Java’s core libraries - Stack Overflow

工厂模式:Calendar 原型:Object.Clone

装饰者:Collections#synchronizedxxx() 享元:Integer#valueOf()

策略模式:Comparator#compare()