哈哈,我來了,我又來了,在這年關將至的時候,趁有時間,就多學習和溫習點老的知識。咱們在.net core開發中,會常常使用注入來注入一個單例類,而在沒有注入的時候,大部分狀況會本身實現一個單例類,或者更簡單的就是實現一個靜態類。而經常在使用中,都能完成特定的目的,然而它們間的區別是什麼呢?編程
單例模式:屬於設計模式中建立類型的模式,經過單例模式的方法建立的類,在當前程序中只有一個實例,固然能夠實現爲線程安全的單例。設計模式
這裏簡單複習下建立代碼:緩存
使用時實例化,多線程應用時,使用不當會有線程安全問題。安全
public class SingletonA{//私有成員,使用時分配內存private static SingletonA _instance = null;//私有構造,杜絕直接new類private SingletonA() { }//獲取實例public static SingletonA GetInstance (){ if (_instance == null) { _instance = new SingletonA(); }return _instance; } } 複製代碼
聲明實例時實例化,多線程應用時,使用不當會有線程安全問題。多線程
public class SingletonB{//私有靜態成員,聲明類實例時,分配private static readonly SingletonB _instance = new SingletonB();//私有構造,杜絕直接new類private SingletonB() { }public static SingletonB GetInstance(){ return _instance; } }複製代碼
推薦這個,經典的線程安全單例實現框架
public class SingletonD{private static SingletonD _instance = null;private static readonly object _lockObject = new object();private SingletonD() { }public static SingletonD GetInstance(){if (_instance == null) {lock (_lockObject) {if (_instance == null) _instance = new SingletonD(); } }return _instance; } }複製代碼
最精簡版ide
public sealed class SingletonC{private SingletonC() { }public static readonly SingletonC Instance = new SingletonC(); }複製代碼
//FileLogger只須要定義成通常的類便可,無需按照單例模式進行實現,固然也不能是靜態類。 public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSingleton<ILogger, FileLogger>(); }複製代碼
咱們基於如下幾個要點進行比較函數
靜態類形如:工具
public static class StaticExample{private static readonly object lockObj = new object();public static void Log(string message){//Write code here to log data.} }複製代碼
特性比較 | 靜態類 | 單例類 |
---|---|---|
是否支持依賴注入 | 否,編譯時提示靜態類型不能做爲類型參數 | 支持 |
內存管理是怎樣的 | 靜態類存儲在託管堆的high frequency heap,僅當應用程序卸載時,才釋放內存 | 單例類的單個實例是靜態的,所以也保存在high frequency heap,當應用程序卸載時,才釋放內存。可是,與只能具備靜態對象的靜態類不一樣,單例類能夠同時具備靜態和非靜態對象。所以,從內存管理的角度來看,當您使用單例類時,能夠利用垃圾回收管理對象。 |
可擴展性 | 您不能繼承靜態類並覆蓋其方法 ;靜態類不能具備擴展方法 | 單例類一般包含一個私有構造函數,並標記爲已密封,以指示它既不能實例化也不能繼承;所以,只有在單例類中具備非私有構造函數的狀況下,才能夠擴展單例類;單例類能夠具備擴展方法 |
可測試性 | 模擬靜態類很是困難,特別是在包含靜態對象的時候。固然若是是隻有靜態方法,且冪等則仍是很容易測試的 | 測試單例類很容易 |
通過上面的對比,你應該看出端倪了。性能
當您只須要一個包含多個方法的工具類時,靜態類是一個不錯的選擇,在這種狀況下您不須要實例。由於您沒有此類的任何實例,因此這個簡單的實現提升了應用程序的性能。
單例模式可用於設計只須要一個實例的類。典型示例包括用於日誌記錄,緩存,線程池等的管理器類,在這些場景,單例類是一個不錯的選擇。爲此,您應該有一個實例,以免對同一資源的請求衝突。 還有在引入了DI框架後,你應該多多使用單例類,由於實現這樣的需求,就是簡單的定義一個普通的類,而後註冊到DI中便可。
固然還有一點就是單例類更加像面向對象編程,哈哈~~~