refactoringguru,sourcemaking。
创建型模式
单例模式
- 提前创建单例:适用于频繁使用,或者单例占用资源较少的情况。最简单创建单例的方式是使用枚举类。
 
- 延迟创建单例:存在多线程问题,可以直接使用 
synchronized 对整个方法进行同步。但实际上只有在第一次调用时才需要同步,所以更优的实现是使用双重检查加锁以及 volatile 关键字。 
- 当使用多个类加载器、反射和序列化/反序列化时,要注意避免创建多个单例实例。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public final class Singleton {
      private volatile static Singleton instance;     public String value;
      private Singleton(String value) {         this.value = value;     }
      public static Singleton getInstance(String value) {         if (instance == null) {             synchronized (Singleton.class) {                 if (instance == null) {                     instance = new Singleton(value);                 }             }         }         return instance;     } }
  | 
 
结构型模式
代理模式
Java 在 java.lang.reflect 包中有自己的代理支持,利用该包可以动态地创建代理类,所以该技术被称为动态代理。
- 实现 
InvocationHandler 接口。 
- 以指定的对象和 
InvocationHandler 实现类为参数,调用 Proxy.newProxyInstance 方法,创建代理对象。 
- 将代理对象强制类型转换为指定的对象所实现的某个接口类型,然后调用方法。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
   | interface Person {
      void foo(); }
  class PersonImpl implements Person {
      @Override     public void foo() {         System.out.println(this.getClass().getName());     } }
  class MyInvocationHandler implements InvocationHandler {
      private Person person;
      public MyInvocationHandler(Person person) {         this.person = person;     }
      @Override     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                  System.out.println(this.getClass().getName());         return method.invoke(person, args);     } }
  class ProxyFactory {
      public static Person getProxyInstance(Person person) {         return (Person) Proxy.newProxyInstance(                 person.getClass().getClassLoader(),                 person.getClass().getInterfaces(),                 new MyInvocationHandler(person));     } }
  public class DynamicProxy {
      public static Person getProxyInstance(Person person) {         return (Person) Proxy.newProxyInstance(                 person.getClass().getClassLoader(),                 person.getClass().getInterfaces(),                 new MyInvocationHandler(person));     }
      public static void main(String[] args) {         Person person = new PersonImpl();         Person proxyInstance = getProxyInstance(person);         proxyInstance.foo();     } }
  |