设计模式--创建型模式-单例模式

单例模式

亦称: 单件模式、Singleton

单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。

问题

单例模式同时解决了两个问题, 所以违反了_单一职责原则_:

1. 保证一个类只有一个实例

2. 为该实例提供一个全局访问节点

解决方案

所有单例的实现都包含以下两个相同的步骤:

  • 将默认构造函数设为私有, 防止其他对象使用单例类的 new运算符。
  • 新建一个静态构建方法作为构造函数。 该函数会 “偷偷” 调用私有构造函数来创建对象, 并将其保存在一个静态成员变量中。 此后所有对于该函数的调用都将返回这一缓存对象。

如果你的代码能够访问单例类, 那它就能调用单例类的静态方法。 无论何时调用该方法, 它总是会返回相同的对象。

单例模式适合应用场景

如果程序中的某个类对于所有客户端只有一个可用的实例, 可以使用单例模式。

单例模式禁止通过除特殊构建方法以外的任何方式来创建自身类的对象。 该方法可以创建一个新对象, 但如果该对象已经被创建, 则返回已有的对象。

如果你需要更加严格地控制全局变量, 可以使用单例模式。

单例模式与全局变量不同, 它保证类只存在一个实例。 除了单例类自己以外, 无法通过任何方式替换缓存的实例。

请注意, 你可以随时调整限制并设定生成单例实例的数量, 只需修改 获取实例方法, 即 getInstance 中的代码即可实现。

实现方式

  1. 在类中添加一个私有静态成员变量用于保存单例实例。
  2. 声明一个公有静态构建方法用于获取单例实例。
  3. 在静态方法中实现"延迟初始化"。 该方法会在首次被调用时创建一个新对象, 并将其存储在静态成员变量中。 此后该方法每次被调用时都返回该实例。
  4. 将类的构造函数设为私有。 类的静态方法仍能调用构造函数, 但是其他对象不能调用。
  5. 检查客户端代码, 将对单例的构造函数的调用替换为对其静态构建方法的调用。

举例实现–懒汉模式(加锁判断)

#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;
}

结果

0x2216e70 0x2216e70   //相同的地址

举例实现–饿汉模式(初始化时候构造)

#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;
}

结果

Singleton works, both variables contain the same instance.

猜你喜欢

转载自blog.csdn.net/qq_40513792/article/details/113526050
今日推荐