Reference: refactoringguru. Cn/design – patt…

intentions

The singleton pattern is a creative design pattern that allows you to ensure that there is only one instance of a class and provide a global node to access that instance.

The problem

The singleton pattern solves two problems

  1. Ensure that there is only one instance of a class. Each call to the normal constructor returns a new object. The singleton ensures that each time a new object is created, one of the created objects is returned.
  2. Provide a global access node for the instance. Like global variables, the singleton pattern allows specific objects to be accessed from anywhere in the program. But it protects the instance from being overwritten by other code.

The solution

The implementation of the singleton pattern involves the following two steps:

  1. Make the default constructor private to prevent other objects from using the singleton classnewOperator.
  2. Create a new static build method as a constructor. This function “surreptitiously” calls the private constructor to create the object and store it in a static member variable. All subsequent calls to this function will return the cache object.

Singleton pattern structure

  1. The singletonThe (Singleton) class declares a class namedget­InstanceA static method that gets an instance to return an identical instance of its class. This method is the only way to get a singleton.

Code implementation

#include<iostream>
#include<string>
using namespace std;

class Singleton {
private:
	// Member variables that hold singletons must be declared statically typed.
	static Singleton* singleton_;
	// The constructor of a singleton must always be a private type to prevent the constructor from being called directly with the 'new' operator
	// Build method.
	Singleton(const std::string value) : value_(value)
	{
	}
	string value_;

public:
	Singleton(Singleton& other) = delete;
	void operator= (const Singleton&) = delete;
	Static methods used to control access to a singleton instance.
	static Singleton* get_instance(const string& value);

	// Any singleton must define some business logic that can be executed on instances.
	void SomeBusinessLogic(a)
	{
		cout << "value/2:" << singleton_->value_/2 << endl;
	}

	std::string value(a) const {
		returnvalue_; }}; Singleton* Singleton::singleton_ =nullptr;
Singleton *Singleton::get_instance(const std::string& value)
{
	if (singleton_ == nullptr) {
		singleton_ = new Singleton(value);
	}
	return singleton_;
}

int main(a) {
	Singleton* singleton1 = Singleton::get_instance("FOO");
	Singleton* singleton2 = Singleton::get_instance("Bar");

	// If values are the same, the singleton is valid
	cout << singleton1->value() << endl;
	cout << singleton2->value() << endl;

	return 0;
}
Copy the code

The above implementation is not safe if multiple threads are requesting the singleton at the same time. Therefore, thread synchronization is required, using thread-safe singletons.

Advantages and disadvantages of this mode

  1. advantages
    • You can guarantee only one instance of a class.
    • You get a global access node that points to the instance.
    • A singleton is initialized only when it is first requested.
  2. disadvantages
    • It violates the single responsibility principle. This pattern solves two problems simultaneously
    • This mode requires special processing in multi-threaded environment to avoid multiple threads creating singleton objects.
    • The singleton pattern can mask bad design, such as too much knowledge between the components of a program.