常用设计模式

Posted by keys961 on February 3, 2018

常用设计模式

具体可见链接 Click Here.本文使用中文且稍微有所扩展,前面的链接包含了23种设计模式,这里说常用的10个.

  1. 单例:不同的写法,

    • 懒汉式,线程不安全(最基础的单例)

    • 懒汉式,线程安全(直接加synchronized)

    • 饿汉式(直接静态就加载,不延迟,利用类加载机制避免同步问题,因为虚拟机执行<clinit>(),即类初始化时保证线程安全)

    • 线程安全的DCL(1.5以后,volatile对内存语义有更新,限制了指令重排)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    public class Singleton
    {
    		private static volatile Singleton instance;  	
      	public static Singleton getInstance()
        	{
      		if(instance == null)//Check 1
             {    					
                 synchronized(Singleton.class)//P(monitor)
                 {
                  	if(instance == null)//Check 2
                      	instance = new Singleton();
                 }//V(monitor)
    			}
        		return instance;
    		}
    }
    
    • 静态内部类(静态内部类不会因为外部类被初始化而初始化,而只会当外部类调用内部类成员时先被加载,而这里的加载也被虚拟机保证是线程安全的)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
     public class Singleton
    	{
    		private static class SingletonHolder
         {
             private static final Singleton INSTANCE = new Singleton();
         }
    
      	public static Singleton getInstance()
        	{
      		return SingletonHolder.INSTANCE;
    		}
    	}
    
  2. ​工厂方法/抽象工厂

    • 工厂方法(虚构造器):先定义创建对象的接口(抽象的工厂方法),子类实现这个工厂方法.即创建过程延迟到子类进行.(也可以用泛型,在Java需要反射)

    • 抽象工厂:定义一个抽象工厂,定义了一系列的创建对象的方法,然后具体的工厂就去重写它们.它适用于有多个产品族,但系统只需要创建其中一个产品族的情形.(例如某个产品需要<A,B>,但有很多产品族,如<A1,B1>,<A2,B2>等等,创建工厂时,A和B绑定在一起,一起创建的)

  3. 观察者:一个对象(Subject)状态改变,其所依赖的对象(Observer)会得到通知,通知是广播/组播的.(抽象的)Subject维护了一个(抽象)Observer的列表,当Subject状态改变,则遍历这个列表将通知发给所有的Observer;而(具体的)Observer需要知道自己所观察的Subject,当通知到来的时候可以从Subject中获取其状态.

  4. 适配器(Wrapper):适配器适配接口,并使用了被适配的对象(通过聚合或者多继承,后者适用于C++).通常这个适配器可作为一个Wrapper.

  5. 策略:抽象类/接口Strategy定义一个算法,然后具体的不同的ConcreteStrategy继承它并实现这个算法.外部可以通过这个抽象类/接口并赋予不同的具体策略以调用不同的策略/算法.

  6. 责任链(本质是个链表,链式反应):定义一个Handler,定义了处理请求的方法,并在里面包含它的后继者,用于将请求转发给后继者处理.而具体的ConcreteHandler实现这个接口/抽象类,在处理自己的请求后选择是否将请求转发给下一个Handler.应用: Servlet中的Filter.

  7. 装饰器:装饰者实现/继承接口/抽象类,并聚合了其他具体组件,实现了该具体组件功能的同时也同样在该功能基础上添加了新特性.具体实践有Java IO (Input/OutputStream).

  8. 模板:定义一个操作算法的步骤(在父类/抽象类中),而这些步骤的实现延迟到子类里.

  9. 组合:组件分为单一组件和复合组件,都继承于某个接口/抽象类.而复合组件拥有一组组件(通常用列表保存).可以把单一组件看作叶节点,复合组件作为非叶节点.

  10. 迭代器:见Java Collections, C++ STL的迭代器(例如链表,二叉树迭代器等等).