設計模式之☞單例模式

陳彥斌發表於2019-05-22

簡介

單例模式(Singleton Pattern)是 程式開發 中最簡單的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。

這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。

注意:

  • 1、單例類只能有一個例項。
  • 2、單例類必須自己建立自己的唯一例項。
  • 3、單例類必須給所有其他物件提供這一例項。

介紹

意圖:保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。

主要解決:一個全域性使用的類頻繁地建立與銷燬。

何時使用:當您想控制例項數目,節省系統資源的時候。

如何解決:判斷系統是否已經有這個單例,如果有則返回,如果沒有則建立。

關鍵程式碼:建構函式是私有的。

優點:

  • 1、在記憶體裡只有一個例項,減少了記憶體的開銷,尤其是頻繁的建立和銷燬例項(比如管理學院首頁頁面快取)。
  • 2、避免對資源的多重佔用(比如寫檔案操作)。

缺點:沒有介面,不能繼承,與單一職責原則衝突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來例項化。

案例一(無執行緒):

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 單例模式演示
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             Singleton obj =Singleton.CreateInstance();
14             Singleton obj2 = Singleton.CreateInstance();
15             Singleton obj3 = Singleton.CreateInstance();
16             Console.ReadKey();
17         }
18         /// <summary>
19         /// 當把一個類的建構函式的訪問修飾符設為private後,那麼這個類外部就不可以被建立物件了
20         /// </summary>
21         public class Singleton
22         {
23             /// <summary>
24             /// 重寫建構函式
25             /// </summary>
26             private Singleton()
27             {
28                 Console.WriteLine('.');
29             }
30             private static Singleton _instance;
31             /// <summary>
32             /// 建立例項
33             /// </summary>
34             /// <returns></returns>
35             public static Singleton CreateInstance()
36             {
37                 if (_instance==null)
38                 {
39                     _instance = new Singleton();
40                 }
41                 return _instance;
42             }
43         }
44     }
45 }

注:上述方法加入執行緒操作

案例二(有執行緒單例模式處理,效率受點影響,必須等執行緒執行完,才會繼續執行其他的執行緒)

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Threading;
 7 
 8 namespace 單例模式之多執行緒
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             for (int i = 0; i < 1000; i++)
15             {
16                 Thread t = new Thread(new ThreadStart(() =>
17                 {
18                     Singleton s = Singleton.CreateInstance();
19                 }));
20                 t.Start();
21             }
22             Console.WriteLine("ok");
23             Console.ReadKey();
24         }
25         /// <summary>
26         /// 當把一個類的建構函式的訪問修飾符設為private後,那麼這個類外部就不可以被建立物件了
27         /// </summary>
28         public class Singleton
29         {
30             /// <summary>
31             /// 重寫建構函式
32             /// </summary>
33             private Singleton()
34             {
35                 Console.WriteLine(".");
36             }
37             private static Singleton _instance;
38             private static readonly object syn = new object();
39             /// <summary>
40             /// 建立例項
41             /// </summary>
42             /// <returns></returns>
43             public static Singleton CreateInstance()
44             {
45                 lock (syn) //加鎖
46                 {
47                     if (_instance == null)
48                     {
49                         _instance = new Singleton();
50                     }
51                 }
52                 return _instance;
53             }
54         }
55     }
56 }

案例三(推薦,既保持了單例模式,又提高了效能):

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Threading;
 7 
 8 namespace 單例模式之多執行緒最優方法
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             for (int i = 0; i < 1000; i++)
15             {
16                 Thread t = new Thread(new ThreadStart(() =>
17                 {
18                     Singleton s = Singleton.CreateInstance();
19                 }));
20                 t.Start();
21             }
22             Console.WriteLine("ok");
23             Console.ReadKey();
24         }
25         /// <summary>
26         /// 當把一個類的建構函式的訪問修飾符設為private後,那麼這個類外部就不可以被建立物件了
27         /// </summary>
28         public class Singleton
29         {
30             /// <summary>
31             /// 重寫建構函式
32             /// </summary>
33             private Singleton()
34             {
35                 Console.WriteLine(".");
36             }
37             private static Singleton _instance;
38             private static readonly object syn = new object();
39             /// <summary>
40             /// 建立例項
41             /// </summary>
42             /// <returns></returns>
43             public static Singleton CreateInstance()
44             {
45                 if (_instance == null)
46                 {
47                     lock (syn) //加鎖
48                     {
49                         if (_instance == null)
50                         {
51                             _instance = new Singleton();
52                         }
53                     }
54                 }
55                 return _instance;
56             }
57         }
58     }
59 }

 專案連結:https://pan.baidu.com/s/1EpGurdSHqzUmEd7Ta6z7mQ 

提取碼:fd9s

相關文章