Monday, October 12, 2015

Improve the knowledge about SingletonDesign Patterns

Singleton




Definition
Ensure a class has only one instance and provide a global point of access to it.







UML class diagram








Participants


    The classes and objects participating in this pattern are:
  • Singleton   (LoadBalancer)
    • defines an Instance operation that lets clients access its unique instance. Instance is a class operation.
    • responsible for creating and maintaining its own unique instance.





Structural code in C#


This structural code demonstrates the Singleton pattern which assures only a single instance (the singleton) of the class can be created.
1.                   
2.   
3.  using System;
4.   
5.  namespace DoFactory.GangOfFour.Singleton.Structural
6.  {
7.    /// <summary>
8.    /// MainApp startup class for Structural
9.    /// Singleton Design Pattern.
10.   /// </summary>
11.   class MainApp
12.   {
13.     /// <summary>
14.     /// Entry point into console application.
15.     /// </summary>
16.     static void Main()
17.     {
18.       // Constructor is protected -- cannot use new
19.       Singleton s1 = Singleton.Instance();
20.       Singleton s2 = Singleton.Instance();
21.  
22.       // Test for same instance
23.       if (s1 == s2)
24.       {
25.         Console.WriteLine("Objects are the same instance");
26.       }
27.  
28.       // Wait for user
29.       Console.ReadKey();
30.     }
31.   }
32.  
33.   /// <summary>
34.   /// The 'Singleton' class
35.   /// </summary>
36.   class Singleton
37.   {
38.     private static Singleton _instance;
39.  
40.     // Constructor is 'protected'
41.     protected Singleton()
42.     {
43.     }
44.  
45.     public static Singleton Instance()
46.     {
47.       // Uses lazy initialization.
48.       // Note: this is not thread safe.
49.       if (_instance == null)
50.       {
51.         _instance = new Singleton();
52.       }
53.  
54.       return _instance;
55.     }
56.   }
57. }
58.  
59.     
60.         
61.             


Output
Objects are the same instance






Real-world code in C#


This real-world code demonstrates the Singleton pattern as a LoadBalancing object. Only a single instance (the singleton) of the class can be created because servers may dynamically come on- or off-line and every request must go throught the one object that has knowledge about the state of the (web) farm.
1.                   
2.   
3.  using System;
4.  using System.Collections.Generic;
5.  using System.Threading;
6.   
7.  namespace DoFactory.GangOfFour.Singleton.RealWorld
8.  {
9.    /// <summary>
10.   /// MainApp startup class for Real-World
11.   /// Singleton Design Pattern.
12.   /// </summary>
13.   class MainApp
14.   {
15.     /// <summary>
16.     /// Entry point into console application.
17.     /// </summary>
18.     static void Main()
19.     {
20.       LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
21.       LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
22.       LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
23.       LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
24.  
25.       // Same instance?
26.       if (b1 == b2 && b2 == b3 && b3 == b4)
27.       {
28.         Console.WriteLine("Same instance\n");
29.       }
30.  
31.       // Load balance 15 server requests
32.       LoadBalancer balancer = LoadBalancer.GetLoadBalancer();
33.       for (int i = 0; i < 15; i++)
34.       {
35.         string server = balancer.Server;
36.         Console.WriteLine("Dispatch Request to: " + server);
37.       }
38.  
39.       // Wait for user
40.       Console.ReadKey();
41.     }
42.   }
43.  
44.   /// <summary>
45.   /// The 'Singleton' class
46.   /// </summary>
47.   class LoadBalancer
48.   {
49.     private static LoadBalancer _instance;
50.     private List<string> _servers = new List<string>();
51.     private Random _random = new Random();
52.  
53.     // Lock synchronization object
54.     private static object syncLock = new object();
55.  
56.     // Constructor (protected)
57.     protected LoadBalancer()
58.     {
59.       // List of available servers
60.       _servers.Add("ServerI");
61.       _servers.Add("ServerII");
62.       _servers.Add("ServerIII");
63.       _servers.Add("ServerIV");
64.       _servers.Add("ServerV");
65.     }
66.  
67.     public static LoadBalancer GetLoadBalancer()
68.     {
69.       // Support multithreaded applications through
70.       // 'Double checked locking' pattern which (once
71.       // the instance exists) avoids locking each
72.       // time the method is invoked
73.       if (_instance == null)
74.       {
75.         lock (syncLock)
76.         {
77.           if (_instance == null)
78.           {
79.             _instance = new LoadBalancer();
80.           }
81.         }
82.       }
83.  
84.       return _instance;
85.     }
86.  
87.     // Simple, but effective random load balancer
88.     public string Server
89.     {
90.       get
91.       {
92.         int r = _random.Next(_servers.Count);
93.         return _servers[r].ToString();
94.       }
95.     }
96.   }
97. }
98.  
99.         
100.                        


Output
Same instance

ServerIII
ServerII
ServerI
ServerII
ServerI
ServerIII
ServerI
ServerIII
ServerIV
ServerII
ServerII
ServerIII
ServerIV
ServerII
ServerIV


No comments:

Post a Comment