理解設計模式之單例模式和原型模式

2022-10-10 13:21:12 字數 3835 閱讀 2464

//單例模式:就是乙個能保證在整個程序中只有乙個例項的類

一.想實現單例模式首先就不能把建構函式公開(私有化建構函式)。

//1.私有化建構函式

private singleton()

二.那如何例項化呢?提供乙個公開的靜態方法。

//2.公開的靜態方法提供例項

public static singleton createinstance()

三.通過第二步我們會發現這樣寫每次還是會產生乙個新的例項。如何解決呢?

//3.提供乙個靜態變數保證重用

private static singleton _singleton = null;

這個時候我們就可以改造一下靜態方法了

public static singleton createinstance()

return _singleton;

}

如下就可以基本實現單例模式了

寫成這樣就完了嗎?不可能 新的問題就來了 

在靜態方法中這個判斷只能存在於單執行緒中 如果有多個執行緒同時訪問這個方法 就會失效

很明顯 這個例項被構造了三次,這就已經錯了

如何解決這個問題呢,對於多執行緒併發的問題首先想到的就是最暴力的方法,加鎖

雙判斷鎖(懶漢式寫法)

什麼叫雙判斷鎖呢?我們接著往下看

多執行緒加鎖這個問題大家應該都是很熟悉的

首先定義

private static readonly object singleton_look = new object();

接著我們可以改造方法

public static singleton createinstance()

return _singleton;

}

}

這樣就能絕對的保證不會有併發的問題,都是乙個個的進來的,所以也不會有多個例項

這樣就完成了嗎?並不是,多執行緒加鎖了那和單執行緒有什麼區別呢!所以我們還需要對這個方法進行改造

public static singleton createinstance()

}

}

return _singleton;

}

看完這個**,疑問就來了,為什麼要寫重複的判斷呢,我們看下面這段**

lock (singleton_look)

}

當有執行緒執行到_singleton = new singleton()的時候,後面所有排隊的執行緒進入後都會直接判斷_singleton != null 然後執行返回,這樣的邏輯是很浪費的

所以我們在最外層再包一層判斷,能保證只要有執行緒例項化物件以後,後面所有執行緒不需要走到限制鎖這裡,會直接返回掉

完整**如下:

為啥這個稱為懶漢式的呢

我們在這個類中寫乙個這樣的靜態方法進行呼叫

public static void test()

我們會發現,呼叫方法的時候,這個singleton例項其實還是空的

所以懶漢式寫法在你不主動去呼叫createinstance方法的時候,都不會進行例項化

靜態建構函式(餓漢式)

使用底層clr的機制來實現單例模式

**如圖:

為什麼這種方式稱之為餓漢式呢,在我們除錯的時候就會看到,在呼叫test方法的時候,首先靜態欄位會被呼叫,然後就會執行到靜態構造方法

再才會執行到test方法,

同樣我們用多執行緒進行測試

沒有問題

通過除錯,細心的小夥伴這個時候就可以發現,靜態欄位也會和靜態建構函式一樣,在test前執行,所以我們的**可以進行簡化

我們可以直接連靜態建構函式都不用了,直接通過靜態欄位來初始化

我們來測試一下

同樣也沒有問題,這都是基於clr底層的機制來實現的

********************單例和單執行緒沒有關係!!!!!***********************************

*此處注意乙個問題,可能工作中呼叫例項內中某乙個方法,只要執行到這裡就報錯,但是又找不到問題所在,就可以考慮下是不是靜態建構函式內寫的東西報錯了

其實單例並不是乙個好東西,他是有代價的,用了單例,那這個例項就是常駐記憶體的不會被**

可以用到單例的地方:執行緒池,資料庫連線池,配置檔案物件,ioc容器例項等會需要使用到單例;

我們學完單例模式,有乙個跟單例模式相似的模式叫原型模式,**特別的簡單,一看就能會

話不多說我們先看**

小夥伴們是不是很疑惑,這個跟單例模式有什麼區別

其實這個是通過memberwiseclone()來進行記憶體複製操作,每次都是乙個新的例項

我們都知道,引用型別的變數會在堆裡面開闢一塊空間,而memberwiseclone會對這個空間進行記憶體層面的複製

這樣每次都是乙個新的例項返回出去

看完解讀,又懵了,那我要這個模式有什麼用,正常例項化不是一樣嗎?

這個設計模式後面的每一次返回新例項,都是不會走建構函式的,所以如果你需要這個物件很多次,但是建構函式裡又有很多不需要的複雜邏輯,我們就可以通過原型模式來進行建立物件,提高效率

以上就是我最近學習的一些內容,若有錯誤請多多指點!!!!!

設計模式 單例模式 建造者模式 原型模式

通常我們讓乙個全域性變數使得乙個物件被訪問,但它不能防止你例項化多個物件。乙個最好的辦法就是,讓類自身負責八寸他的唯一例項。這個類可以保證沒有其他例項可以被建立,並且它可以提供乙個訪問該例項的方法。單例模式 singletion 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。這裡寫描述 優...

python原型模式和單例模式學習

實現 import copy class website def init self,name,domain,description,author,kwargs examples of optional attributes kwargs category,creation date,technol...

設計模式之建立型模式 單例模式

在單例模式下,乙個類負責建立自己的例項,且這個類只能建立乙個唯一的例項物件,外部可以直接訪問這個例項物件,單例模式常用於物件的建立。建立單例模式時,建構函式是私有的這樣才能保障,在外部無法建立類例項化物件。單列模式的優點 1 保證在記憶體中只有乙個當前類的例項化物件,減小記憶體的開銷 2 避免資源的...