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
ServerIII
ServerII
ServerI
ServerII
ServerI
ServerIII
ServerI
ServerIII
ServerIV
ServerII
ServerII
ServerIII
ServerIV
ServerII
ServerIV

No comments:
Post a Comment