【.Net邊角料系列】1-單例模式(我真不是你想的那樣)


  • 什么事邊角料

邊角料就是你編程的時候,很少能夠用上,或者說你壓根就不知道得東西,我就稱這些東西為邊角料。這個叫.net邊角料可能有點大,其實這個系列是純粹的C#邊角料系列。

為什么寫.net邊角料呢,因為.net coder越來越少了,所以邊角的東西,知道的人也越來越少,雖然價值不大,但是要抱着拋磚引玉的思想,把更多的人留在.net上,助力.net core紅紅火火大發展——之后我好轉其他語言。就是這種拉一個人下水是一個,倆個人下水賺一個的精神支持着我,希望我能把.net邊角料系列寫完。我不是代碼的生產者,只是代碼的搬運工,所以對於邊角料出現的代碼如果有開源代碼地址,我一定會將開源代碼位置附上,以供下水者沉迷其中,不能自拔。

  • 邊角料的單例模式

如果說單例模式是邊角料,估計我會挨噴,基本每次面試都可能被問到,而且不懂單例模式,好意思說自己是一個.net程序員嗎?所以咱們這談的不是傳統的單例模式,更不會談什么線程安全性,以及懶加載、惰性加載的問題。

不過也得問一句,單例模式符合設計模式的六大原則嗎?至少單一職責原則,它不符合。它既要保證自己單例又要保證自己原有意義。設計模式上沒有什么是拆分辦不到的,如果辦不到,那就再拆分一次。

所以下面我們正式介紹我們的邊角料——泛型單例

  • 源碼及地址

沒有什么比源碼更有說服力了,首先上源碼地址:nopCommerce(https://github.com/nopSolutions/nopCommerce)這個是大名鼎鼎的nopCommerce,具體它有多牛,自行百度,反正我也不知道。類文件叫做:Singleton.cs

 

 1    public class Singleton<T> : Singleton
 2     {
 3         static T instance;
 4         public static T Instance
 5         {
 6             get { return instance; }
 7             set
 8             {
 9                 instance = value;
10                 AllSingletons[typeof(T)] = value;
11             }
12         }
13     }
14 
15     public class SingletonList<T> : Singleton<IList<T>>
16     {
17         static SingletonList()
18         {
19             Singleton<IList<T>>.Instance = new List<T>();
20         }
21         public new static IList<T> Instance
22         {
23             get { return Singleton<IList<T>>.Instance; }
24         }
25     }
26 
27     public class SingletonDictionary<TKey, TValue> : Singleton<IDictionary<TKey, TValue>>
28     {
29         static SingletonDictionary()
30         {
31             Singleton<Dictionary<TKey, TValue>>.Instance = new Dictionary<TKey, TValue>();
32         }
33 
34         public new static IDictionary<TKey, TValue> Instance
35         {
36             get { return Singleton<Dictionary<TKey, TValue>>.Instance; }
37         }
38     }
39 
40 
41     public class Singleton
42     {
43         static Singleton()
44         {
45             allSingletons = new Dictionary<Type, object>();
46         }
47 
48         static readonly IDictionary<Type, object> allSingletons;
49 
50         public static IDictionary<Type, object> AllSingletons
51         {
52             get { return allSingletons; }
53         }
54     }
  •  代碼分析

單例模式就是設計模式最最簡單的了,泛型單例也是簡單到令人發指。代碼分析有什么說的呢,不過為了湊篇幅,強說兩句吧。

1.這里面一共有四個類:Singleton、Singleton<T>、SingletonList<T>、SingletonDictionary<TKey, TValue>。繼承關系是Singleton<T>集成自Singleton,而SingletonList<T>、SingletonDictionary<TKey, TValue>繼承自Singleton<T>.

對於不熟悉泛型的同學來說,我可以拍胸脯的告訴你,泛型類可以繼承自非泛型類,非泛型類可以繼承自泛型類,只要你想沒啥不可以的。

2.對於這四個類,所有內容都是靜態的——構造函數、字段、屬性。對於靜態構造函數,這個和普通構造函數不同的地方有三:首先它只用於初始化靜態變量,其次靜態構造函數不供其他類調用(所以不能用public、private修飾),只夠clr初始化的時候調用。最后靜態構造函數不能有參數列表,因為沒人能給它傳參。

3.對於泛型來說,List<int>和List<string>是倆個完全不同的類,所以盡管SingletonList<T>只有一個靜態變量,但是對於已經非泛化(具體類型代入后)的各個類型,都有自己的靜態變量,所以每個T類型都對應SingletonList<T>的Instance屬性,所以泛型類能夠保證每個實例都能是全局唯一——也就是單例模式。

4.對於Singleton非泛型類,他唯一的作用就是提供一個集合,供其他對象檢索,哪些類型已經被泛型單例類緩存了。這完全不是必須的。但是他給我們提了一個醒:對於非泛型類每個類單獨所有的靜態變量,要放到泛型類的父類中。換句話說,就是泛型類出現靜態變量要慎重,是不是要放到父類中。

  • 實用的代碼

泛型單例這段源碼,雖然高大上,但是不一定符合我們的要求,所以我們有時候有實用的要求,下面就供上我簡化的泛型單例源碼.

    public class Singleton<T> where T:new()
    {
        static T instance=new T();
        public static T Instance
        {
            get { return instance; }
            set
            {
                instance = value;
            }
        }
    }
  • 說到最后

雖然泛型單例確實是邊角料,但是泛型靜態構造函數、以及nopCommerce絕對不是邊角料。願這些似是而非的邊角料,對你有益。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM