Modo de diseño-modo de creación-modo singleton

Modo singleton

También conocido como: modo único, Singleton

El patrón singleton es un patrón de diseño de creación que le permite asegurarse de que solo haya una instancia de una clase y proporcionar un nodo global para acceder a esa instancia.

problema

El modo singleton resuelve dos problemas al mismo tiempo, por lo que viola el _principio de responsabilidad única_:

1. Asegúrese de que solo haya una instancia de una clase .

2. Proporcione un nodo de acceso global para la instancia.

solución

La realización de todos los singleton incluye los siguientes dos pasos idénticos:

  • El constructor predeterminado es privado, para evitar que otros objetos utilicen una única clase de newoperador de realizaciones .
  • Cree un nuevo método de construcción estático como constructor. Esta función llamará "secretamente" al constructor privado para crear el objeto y guardarlo en una variable miembro estática. Todas las llamadas posteriores a esta función devolverán este objeto de caché.

Si su código puede acceder a la clase singleton, entonces puede llamar al método estático de la clase singleton. Siempre que se llame a este método, siempre devolverá el mismo objeto.

El modo singleton es adecuado para escenarios de aplicación

Si una determinada clase en el programa tiene solo una instancia disponible para todos los clientes, puede usar el modo singleton.

El modo Singleton prohíbe la creación de objetos de su propia clase por cualquier medio que no sean métodos de construcción especiales. Este método puede crear un nuevo objeto, pero si el objeto ya ha sido creado, devuelve el objeto existente.

Si necesita controlar las variables globales de forma más estricta, puede utilizar el modo singleton.

El modo singleton es diferente de las variables globales en que garantiza que solo hay una instancia de la clase. Excepto por la propia clase singleton, la instancia en caché no se puede reemplazar de ninguna manera.

Tenga en cuenta que siempre puede ajustar y establecer la unidad de generación de número límite de los ejemplos de realización, solo 获取实例se puede realizar un método de modificación , es decir, el código getInstance.

Método para realizar

  1. Agregue una variable miembro estática privada a la clase para guardar la instancia de singleton.
  2. Declare un método de construcción estático público para obtener instancias de singleton.
  3. Implemente la "inicialización retrasada" en un método estático. Este método crea un nuevo objeto cuando se llama por primera vez y lo almacena en una variable miembro estática. Después de eso, el método devolverá esta instancia cada vez que se llame.
  4. Haga que el constructor de la clase sea privado. Los métodos estáticos de la clase aún pueden llamar al constructor, pero otros objetos no pueden llamarlo.
  5. Verifique el código del cliente y reemplace la llamada al constructor del singleton con una llamada a su método de construcción estático.

Ejemplo de implementación: modo de hombre perezoso (juicio de bloqueo)

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

class HttpServer 
{
    
    
public :
    static HttpServer *getInstance() 
    {
    
    
        if (instance == nullptr) 
        {
    
    
        /* 当第一个线程执行到此,对locker对象 "加锁",
           当第二个线程执行到此,如果检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁后再继续执行
           lock语句执行完也即代表上一个线程执行结束,同时对该对象"解锁"
           */
            std::unique_lock<std::mutex> lock(m_mutex);
            if (instance == nullptr) 
            {
    
    
                instance = new HttpServer();
            }
        }
        return instance;
    }
private:
    static HttpServer *instance;   定义一个用于保存静态变量的实例
    static std::mutex m_mutex;
    HttpServer() {
    
    }   //构造函数
    HttpServer(const HttpServer &) = delete;  //默认拷贝构造
    ~HttpServer() {
    
    }   //析构函数
};

HttpServer *HttpServer::instance = nullptr;
std::mutex HttpServer::m_mutex;

int main() 
{
    
    
    HttpServer *t1 = HttpServer::getInstance();
    HttpServer *t2 = HttpServer::getInstance();
    cout << t1 << " " << t2 << endl;
    return 0;
}

resultado

0x2216e70 0x2216e70   //相同的地址

Ejemplo de modo de hombre hambriento de implementación (construido durante la inicialización)

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

class HttpServer 
{
    
    
public :
    static HttpServer *getInstance() 
	{
    
     
        	return instance;
    }
private:
    static HttpServer *instance;   定义一个用于保存静态变量的实例
    static std::mutex m_mutex;
    HttpServer() {
    
    }   //构造函数
    HttpServer(const HttpServer &) = delete;  //默认拷贝构造
    ~HttpServer() {
    
    }   //析构函数
};

HttpServer *HttpServer::instance = new HttpServer();  
std::mutex HttpServer::m_mutex;

int main() 
{
    
    
    HttpServer *t1 = HttpServer::getInstance();
    HttpServer *t2 = HttpServer::getInstance();
    if (t1 == t2)
	{
    
    
       cout<<("Singleton works, both variables contain the same instance.")<< endl;
    }
    else
    {
    
    
       cout<<("Singleton failed, variables contain different instances.")<< endl;
     }
    return 0;
}

resultado

Singleton works, both variables contain the same instance.

Supongo que te gusta

Origin blog.csdn.net/qq_40513792/article/details/113526050
Recomendado
Clasificación