設計模式系列

wangqingxu_hold發表於2019-04-02

軟體設計模式(DesignPattern)

Java中一般常用的設計模式有23種,其中常用的幾種設計模式應該去掌握。 總體來說設計模式分為三大類: 建立型模式,共5種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。 結構型模式,共7種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。 行為型模式,共11種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。

單例模式

1、什麼是單例模式?

百度百科是這樣定義的:單例模式是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個例項

我是這樣理解的:單例模式就是隻允許一個例項,最開始使用它的時候是C#中,我要例項化一個A窗體,但是有個需求就是A窗體必須是唯一,不管我在B窗體操作A窗體還是C窗體中操作A窗體都是如此,這時候就使用到了單例模式。

2、單例模式分類

  • 懶漢單例模式:在第一次呼叫的時候例項化本身,在併發環境下,可能出現多個本身物件。所以執行緒是不安全的。

  • 餓漢單例模式:在類初始化時,已經自行例項化一個靜態物件,所以本身就是執行緒安全的。

  • 登記單例模式:通過一個專門的類對各單例模式的單一例項進行管理和維護。

  • 列舉模式

3、特點

A、 單例模式類只能有一個例項 B、 單例模式類必須自己建立自己的唯一例項 C、 單例模式類必須給所有其他物件提供這一例項

程式碼示例

1:懶漢模式example
public class SingleExample {
	
	/**
	 * 該函式限制使用者主動建立例項
	 */
	private SingleExample() {}
	private static SingleExample singleExample= null;
	
	/**
	 * 獲取SingleExample例項(也叫靜態工廠方法)
	 * @return SingleExample
	 */
	public static SingleExample getSingleExample() {
		/* SingleExample為空時建立它,反之直接返回,保證唯一性 */
		if(singleExample == null){
			singleExample = new SingleExample();
		}
		return singleExample;
	}
	
}
複製程式碼

一種更好的單例實現方式

public class SingleExample {
	/**
	 * 類級的內部類,也就是靜態類的成員式內部類,該內部類的例項與外部類的例項
	 * 沒有繫結關係,而且只有被呼叫時才會裝載,從而實現了延遲載入
	 * @author dream
	 *
	 */
	private static class SingleExampleHolder{
		/**
		 * 靜態初始化器,由JVM來保證執行緒安全
		 */
		private static final SingleExample instance = new SingleExample();
	}
	
	/**
	 * 私有化構造方法
	 */
	private SingleExample(){
		
	}
	
	public static SingleExample getInstance(){
		return SingleExampleHolder.instance;
	}
}

複製程式碼
2:餓漢模式example
public class SingleExample {

	/**
	 * 該函式限制使用者主動建立例項
	 */
	private SingleExample() {}

	private static final SingleExample singleExample = new Singleton();

	/**
	 * 獲取SingleExample例項,也叫靜態工廠方法
	 * @return SingleExample
	 */
	public static SingleExample getInstance() {
		return SingleExample;
	}
}
複製程式碼
3:登記模式example(靜態內部類)
public class SingleExample {

	// 儲存需要進行維護和管理的類的例項
	private static Map<String, SingleExample> map = new HashMap<String, SingleExample>();
	
	/**
	 * 靜態建立例項並新增到Map集合
	 */
	static {
		SingleExample singleExample = new SingleExample();
		map.put(SingleExample.getClass().getName(), singleExample);//運用了反射
	}

	/**
	 * 該函式限制使用者主動建立例項
	 */
	private SingleExample() {};

  /**
      * 靜態工廠方法,返回指定登記物件的唯一例項
      * 對於已經登記的直接取出返回,對於還未登記的先登記,然後取出返回
      *
      */
     public static RegMap getInstance(String name){
         if(name==null){
             name="SingleExample";
         }
         if(map.get(name)==null){
             try {
                 map.put(name, (RegSingleton) Class.forName(name).newInstance());
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
         return map.get(name);
     }

}
複製程式碼

何時選用單例模式 當需要控制一個類的例項只能有一個,而且客戶只能從一個全域性訪問點訪問它時,可以選用單例模式,這些功能恰好是單例模式要解決的問題。

相關文章