Overview
The Singleton mode requires that a class has only one instance and provides a global access point. This raises a question: how to bypass the conventional constructor and provide a mechanism to ensure that a class has only one instance? When a customer program calls a class, it does not consider whether the class can only have one instance or other issues. Therefore, this should be the responsibility of the class designer, not the responsibility of the class user.
From another perspective, the singleton model is actually a responsibility model. Because we have created an object and this object plays a unique role, in this separate object instance, it concentrates all the power of the class to which it belongs, at the same time, it is also responsible for exercising this kind of power!
Intention
Ensure that a class has only one instance and provides a global access point to it.
Model Diagram
Logical Model diagram:
Physical Model diagram:
Examples in life
The position of the U.S. president is Singleton. The U.S. Constitution specifies the presidential election, term of office, and succession order. In this way, only one current president can be employed at any time. Regardless of the identity of the current President, his title "President of the United States of America" is a global access point for the person accessing the position.
Five implementations
1. Simple implementation
Public sealed class Singleton
{
Static Singleton instance = NULL;
Singleton ()
{
}
Public static Singleton instance
{
Get
{
If (instance = NULL)
{
Instance = new Singleton ();
}
Return instance;
}
}
}
This method is not secure for threads, because multiple instances of the singleton class may be obtained in a multi-threaded environment. If there are two threads to judge at the same time (instance = NULL) and the result is true, then both threads will create Singleton-like instances, which violates the singleton mode principle. In fact, in the above Code, it is possible that the object instance has been created before the expression value is calculated, but the memory model does not guarantee that the object instance is found before the second thread is created.
This implementation method has two main advantages:
- Because the instance is inInstanceThe property method is created internally, so the class can use additional features (for example, instantiate the subclass), even if it may introduce unwanted dependencies.
- It is called "inert instantiation" until the object requires an instance to be generated ". Inert instantiation avoids unnecessary instantiation during application startupSingleton.
2. Secure thread
Public sealed class Singleton
{
Static Singleton instance = NULL;
Static readonly object padlock = new object ();
Singleton ()
{
}
Public static Singleton instance
{
Get
{
Lock (padlock)
{
If (instance = NULL)
{
Instance = new Singleton ();
}
Return instance;
}
}
}
}
This method is safe for threads. We first create a process secondary object. When the thread enters, it first locks the secondary object and then checks whether the object is created. This ensures that only one instance is created, because only one thread can enter the part of the program that is locked at the same time. In this case, the object instance is created by the first thread to enter. The later thread (instence = NULL) is false and will not be created again. However, this implementation method adds additional overhead and reduces performance.
3. Double Lock
Public sealed class Singleton
{
Static Singleton instance = NULL;
Static readonly object padlock = new object ();
Singleton ()
{
}
Public static Singleton instance
{
Get
{
If (instance = NULL)
{
Lock (padlock)
{
If (instance = NULL)
{
Instance = new Singleton ();
}
}
}
Return instance;
}
}
}
This implementation method is safe for multithreading, And the thread does not lock every time. It is locked only when it determines that the object instance is not created. With the analysis in the first part of the above, we know that after locking, We have to judge whether the object has been created. It solves the thread concurrency problem and avoidsInstanceAn exclusive lock exists in all calls to the property method. It also allows you to delay Instantiation to the first time an object is accessed. In fact, applications seldom need this type of implementation. In most cases, static Initialization is used. This method still has many disadvantages: delayed initialization cannot be implemented.
4. Static Initialization
Public sealed class Singleton
{
Static readonly Singleton instance = new Singleton ();
Static Singleton ()
{
}
Singleton ()
{
}
Public static Singleton instance
{
Get
{
Return instance;
}
}
}
When we see the dramatic code above, we may have doubts. Is this still the singleton mode? In this implementation, an instance is created when any member of the class is referenced for the first time. The Common Language Runtime Library processes variable initialization. This class is markedSealedTo prevent derivation, and the derivation may increase the number of instances. In addition, the variable is markedReadonlyThis means that only variables can be allocated during static initialization (the example shown here) or in the class constructor.
This implementation is similar to the previous example. The difference is that it depends on the Common Language Runtime Library to initialize variables. It can still be used to solveSingletonThe two basic problems that pattern tries to solve: Global Access and instantiation control. The public static attribute provides a global access point for the access instance. In addition, because constructors are private, they cannot be instantiated outside the class itself.SingletonTherefore, a variable references a unique instance that can exist in the system.
BecauseSingletonThe instance is referenced by a private static member variable.InstanceThe property is not instantiated until it is referenced by the call.
The only potential disadvantage of this method is that you have less control over the instantiation mechanism. InDesign Patterns Form, you can use non-default constructor or execute other tasks before instantiation. In this solution. NET FrameworkPerform initialization, so you do not have these options. In most cases, static Initialization is performed in. NetImplementationSingleton.
5. Delayed Initialization
Public sealed class Singleton
{
Singleton ()
{
}
Public static Singleton instance
{
Get
{
Return nested. instance;
}
}
Class nested
{
Static nested ()
{
}
Internal static readonly Singleton instance = new Singleton ();
}
}
Here, the initialization work is completed by a static member of the nested class, which achieves delayed initialization and has many advantages. It is a recommended practice.
Current Mode.
Implementation points
- The Singleton mode is to restrict the creation of classes rather than improve the class.
- The instance constructor In the singleton class can be set to protected to allow subclass derivation.
- The Singleton mode generally does not support the icloneable interface, because it may lead to multiple object instances, which is contrary to the original intention of the singleton mode.
- The Singleton mode generally does not support serialization, which may also lead to multiple object instances, which is contrary to the original intention of the singleton mode.
- Singleton only takes into account the management of object creation, and does not take into account the management of destruction. In terms of the platform and object overhead supporting garbage collection, we generally do not need to perform special management on the destruction.
- The core of understanding and extending the singleton mode is "how to control the arbitrary calls to a class constructor using new ".
- You can easily modify a singleton so that it has a few instances, which is allowed and meaningful.
Advantages
- Instance control:Singleton Will prevent other objects from instantiating their ownSingletonTo ensure that all objects access the unique instance.
- Flexibility: Because the class controls the instantiation process, the class can be more flexible to modify the instantiation process.
Disadvantages
- Overhead: although the number is small, if you want to check whether there is a class instance for every object request reference, you still need some overhead. You can solve this problem by using static initialization, as mentioned in the above five implementation methods.
- Possible development obfuscation: UseSingletonDevelopers must remember that they cannot useNewKeyword instantiation object. Because the source code of the library may not be accessible, application developers may accidentally find that they cannot directly instantiate this class.
- Object Survival:SingletonIt cannot solve the problem of deleting a single object. Among the languages that provide memory management (such as. NET Framework-based languages), onlySingletonClass can cause the instance to be unallocated because it contains a private reference to the instance. In some languages (such as C ++), other classes can be deleted.
Object instance, but this will causeSingletonClass.
Applicability
- When a class can only have one instance and the customer can access it from a well-known access point.
- When this unique instance should be extensible through subclass, and the customer should be able to use an extended instance without changing the code.
Application scenarios
- Each computer can have several printers, but only one printer spooler can be used to prevent two print jobs from being output to the printer at the same time.
(From Lu Zhenyu's C # design model (7)-Singleton pattern)
- The PC may have several serial ports, but only one instance with a COM1 port is allowed.
- There can be only one window manager in the system.
- In. Net remoting, the server activates the sigleton object in the object to ensure that all client program requests are processed by only one instance.
Author: terrylee
Source: http://terrylee.cnblogs.com