23种设计模式-单例(Singleton)设计模式

文章目录

类图: 单例设计模式类图

一.什么是单例设计模式?

单例设计模式 (Singleton Pattern) 是一种创建型设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式通过控制实例的创建过程,避免了重复实例化的开销,常用于全局管理的场景。

二.单例模式的特点

  • 唯一性:单例模式确保一个类只有一个实例。
  • 全局访问点:通过提供一个静态方法获取唯一实例,方便全局访问。
  • 延迟初始化:通常单例实例在第一次使用时初始化,优化性能。

三.单例模式的结构

  • Singleton(单例类) :实现唯一实例的创建逻辑,并提供全局访问方法。

四.单例模式的优缺点

  • 优点:
    • 唯一性保证:确保全局范围内只有一个实例,避免资源浪费。
    • 全局访问:通过统一接口提供访问,简化代码调用。
    • 控制实例生命周期:控制实例的创建和销毁,防止多个实例干扰。
  • 缺点:
    • 多线程复杂性:在多线程环境下需要额外处理线程安全问题。
    • 不易扩展:单例模式本质上限制了类的扩展性。
    • 隐藏依赖:可能导致全局状态被意外修改,影响代码可维护性。

五.单例模式的 C++ 实现

cpp 复制代码
#include <iostream>
#include <mutex>
using namespace std;

// 单例类
class Singleton {
private:
    static Singleton* instance; // 静态实例指针
    static mutex mtx;           // 用于线程安全的互斥锁

    // 私有构造函数,防止外部实例化
    Singleton() {
        cout << "Singleton instance created!" << endl;
    }

    // 禁止拷贝构造和赋值操作
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

public:
    // 静态方法获取唯一实例
    static Singleton* GetInstance() {
        if (instance == nullptr) {  // 检查是否已经存在实例
            lock_guard<mutex> lock(mtx); // 加锁以确保线程安全
            if (instance == nullptr) {  // 双重检查锁定
                instance = new Singleton();
            }
        }
        return instance;
    }

    // 示例方法
    void ShowMessage() {
        cout << "Hello from Singleton instance!" << endl;
    }

    // 销毁单例实例(可选)
    static void DestroyInstance() {
        lock_guard<mutex> lock(mtx);
        if (instance) {
            delete instance;
            instance = nullptr;
            cout << "Singleton instance destroyed!" << endl;
        }
    }
};

// 初始化静态成员
Singleton* Singleton::instance = nullptr;
mutex Singleton::mtx;

// 测试单例模式
int main() {
    Singleton* s1 = Singleton::GetInstance();
    s1->ShowMessage();

    Singleton* s2 = Singleton::GetInstance();
    s2->ShowMessage();

    // 销毁实例(如果需要手动释放内存)
    Singleton::DestroyInstance();

    return 0;
}

六.单例模式的 Java 实现

java 复制代码
public class Singleton {
    // 静态实例变量
    private static Singleton instance;

    // 私有构造函数,防止外部实例化
    private Singleton() {
        System.out.println("Singleton instance created!");
    }

    // 公共静态方法获取唯一实例(线程安全)
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    // 示例方法
    public void showMessage() {
        System.out.println("Hello from Singleton instance!");
    }

    public static void main(String[] args) {
        Singleton s1 = Singleton.getInstance();
        s1.showMessage();

        Singleton s2 = Singleton.getInstance();
        s2.showMessage();
    }
}

七.代码解析

  1. 静态成员变量
    • Singleton* instance 是一个静态指针,用于保存单例类的唯一实例。
    • 静态变量保证在全局范围内只存在一个实例。
  2. 私有构造函数
    • 构造函数被声明为 private,禁止外部通过 new 关键字创建实例。
    • 通过控制实例化的入口,保证类的唯一性。
  3. 线程安全
    • 使用 mutex 和 lock_guard 确保在多线程环境下访问 GetInstance 是安全的。
    • 实现了双重检查锁定(Double-Checked Locking)机制,以避免不必要的锁开销。
  4. 双重检查锁定
    • 第一次检查 if (instance == nullptr),快速跳过锁定代码,提高性能。
    • 第二次检查是为了确保实例在加锁后没有被其他线程创建。
  5. 静态方法 GetInstance
    • 这是访问单例实例的唯一入口,通过静态方法确保全局访问性。
    • 如果实例不存在,则创建;如果已存在,则直接返回。
  6. 销毁单例
    • 提供了 DestroyInstance 方法,用于手动释放单例实例的内存。
    • 销毁操作同样需要加锁以保证线程安全。

八.总结

单例模式是一种简单而实用的设计模式,常用于需要全局唯一实例的场景。C++ 中实现单例模式需要特别注意线程安全和内存管理,而 Java 则通过 synchronized 关键字简化了多线程支持。

单例模式虽然解决了很多全局共享资源的问题,但需要注意避免过度使用,因为全局状态可能会导致代码难以测试和维护。
应用场景:

  • 全局配置管理:如应用程序的配置类或日志管理器。
  • 资源共享:如数据库连接池、线程池等需要共享资源的场景。
  • 控制全局访问:如访问计数器或全局缓存管理器。
相关推荐
ZHOUPUYU6 分钟前
最新SQL Server 2022保姆级安装教程【附安装包】
java·数据库·python·sql·sqlserver·php·sqlserver2022
越努力^越幸运20 分钟前
类和对象--中--运算符重载、日期类实现(重要)
开发语言·c++·算法
IsToRestart23 分钟前
String的设计,用到了哪些设计模式?
java·jvm·设计模式
自律的阿龙33 分钟前
C++练级计划->《多态》虚函数表,菱形继承多态
开发语言·c++
XiaoLeisj35 分钟前
【JavaEE初阶 — 网络编程】TCP流套接字编程
java·开发语言·网络·网络协议·java-ee
MaxCosmos200136 分钟前
读《Effective Java》笔记 - 条目11
java·开发语言·笔记·effective java
yours_Gabriel39 分钟前
【微服务】Nacos配置管理
java·后端·微服务·架构
江-小北1 小时前
Java基础面试题06:hashCode()和equals()方法的重要性体现在什么地方?
java·开发语言
托尼吴1 小时前
第1章-JVM和Java体系架构
java·jvm·架构
大熊的瓜地1 小时前
Android NDK开发 JNI 基础
android·java·ndk