GoF設計模式學習-單例模式

1.目的

控制實例的個數,類設計者應該保證只有一個實例,不能將此責任【只有一個實例】強制交給類使用者。

2.整體實現

1.單線程單例模式的實現。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LearnDesignPattern
{
    public class Singleton
    {
        private Singleton() { }//構造函數私有化,使得用戶無法通過new關鍵字創建對象
        private static Singleton instance;
        public static Singleton Instance
        {
            get
            {//懶加載模式,用戶也可以每次獲取的時候,都new,但是這樣不推薦
                //首先判斷,如果爲第一次使用,則進行new
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
        //注意【1】,C#的單例模式一般使用屬性來獲取Instance
        //而在Java,中一般使用public static Singleton getInstance()的方法,這點不同
        //注意【2】,爲什麼要使用Static關鍵字呢,我們知道Static的關鍵字的作用是
        //可以直接通過類名來進行調用,這樣就保證了,需要先有類的實例才能獲取
        //非static屬性的情況
    }
}

2.多線程單例模式實現:

//如果兩個線程同時判斷instance是不是爲空,當instance==null的時候
    //兩個線程就同時創建出來實例,這樣就存在了兩個實例了
    public class Singleton
    {
       private Singleton() { }
        //volatile:被volatile修飾的變量的值,將不會被本地線程換緩存
        //所有對該變量的讀寫都是直接操作共享內存,從而確保多個線程能
        //正確的處理該變量
        private static volatile Singleton instance;
        //添加線程鎖,確保只有一個線程可以訪問該範圍的代碼,其他線程等待
        private static object objectLock = new object();
        public static Singleton Instance
        {
            //double check雙重檢查機制
            get
            {
                if (instance == null)
                {
                    lock (objectLock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

3.經典的多線程單例模式寫法。

 //【使用靜態構造器】
        //1.靜態構造函數既沒有訪問修飾符,也沒有參數
        //2.在創建第一個實例或引用任何靜態成員之前,將自動調用靜態構造函數來初始化類
        //3.無法直接調用靜態構造函數
        //4.在程序中,用戶無法控制何時執行靜態構造函數
        //【保證1】保證使用類實例或者靜態成員之前初始化
        //【保證2】懶加載,只有在第一次使用,才調用靜態構造器
        //【保證3】.net框架會自動爲多線程加鎖
        public static readonly Singleton Instance = new Singleton();
        private Singleton() { }
        //【弊端】不支持參數化Singleton,因爲傳參必須使用方法來進行!!!GetInstance(object a,object b){}


4.參數化Singleton

//參數化Singleton
        private Singleton(int a,int b)
        {
            this.A = a;//A、B均爲靜態屬性
            this.B = b;//A、B均爲靜態屬性
        }
        public static Singleton GetInstance(int x, int y)
        {
            if (instance == null)
            {
                instance= new Singleton(x, y);
            }
            //可修改單例模式!就相當於修改當前單例的屬性,並不會重新創建新的實例
            else
            {
                instance.A = x;//A、B均爲靜態屬性
                instance.B = y;//A、B均爲靜態屬性
            }
            return instance;
        }

3.思考

1.實例的個數可以兩個麼?三個......多個。使用時,一次創建多個,放在池子中,使用的時候去取。

2.如何將new構造器放到其他類中,實現局部使用一個對象的實例。

3.將new進行屏蔽,然後通過其他方法來實現new的效果【不僅僅是單例】。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章