一、引言
单例模式/单件模式.(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。它的主要目的是控制对某个类的实例化,确保全局只有一个对象可被使用,适用于需要全局共享的对象,如配置文件、数据库连接等。
二、使用场景
-
全局共享资源:当需要一个全局进入点来操作某个共享资源(例如日志、数据库连接或配置管理器)时,使用单例模式是有效的解决方案。
-
避免资源浪费:在创建和维护一个对象需要大量资源的情况下,单例模式可以节省内存和处理时间,避免频繁地创建和销毁对象。
-
限制类的实例数量:在系统中某些类可能从设计上只需一个实例,使用单例模式可以限制并控制其实例化。
-
协调工作进程:在多线程或多进程环境下,单例模式可以用来提供一个共享控制中心。
三、模式分类
- 懒汉式单例:在需要时进行实例化,适用于实例较大,但对于多线程的支持较弱,容易出错。
- 饿汉式单例:在类加载时立刻创建实例,适用于实例较小,线程安全实现简单。
- 线程安全单例:通过使用锁控制实例化,在多线程环境下安全创建实例。
- 双重检查锁定单例:结合懒汉式和线程安全的特点,确保在多线程情景下,也能保持性能上与安全上的平衡。
四、优缺点
优点
- 控制实例数量:能够限制创建类实例的数量,确保类只有一个实例。
- 全局访问:提供全局访问的点,简化了代码的访问方式。
- 延迟实例化:可以在真正需要用到时才创建实例,相比直接在启动时加载增加了灵活性。
缺点
- 难以测试:单例模式会加难进行单元测试,容易造成依赖回环,影响模块化测试。
- 代码复杂性:在使用不当时,可能增加代码的复杂性(如使用懒汉式时可能导致线程安全问题)。
- 隐藏依赖关系:单例模式的将隐含的依赖关系隐藏在实例中,可能增加代码维护的难度。
五、代码示例
以下是一个简单的单例模式的C++实现示例。
#include <iostream>
#include <mutex>
class Singleton {
private:
Singleton() { std::cout << "Singleton Instance Created!\n"; }
~Singleton() { std::cout << "Singleton Instance Destroyed!\n"; }
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static std::once_flag flag_;
static Singleton* instance_;
static void create() { instance_ = new Singleton; }
public:
static Singleton& getInstance() {
std::call_once(flag_, create);
return *instance_;
}
void operation() const {
std::cout << "Executing Operation...\n";
}
};
// 静态成员定义
std::once_flag Singleton::flag_;
Singleton* Singleton::instance_ = nullptr;
int main() {
Singleton::getInstance().operation();
return 0;
}
代码解析
-
Singleton:定义了单例类,使用静态指针
instance
来持有单例对象。 -
构造函数:将构造函数私有化,避免外部直接实例化对象。
-
静态方法
getInstance()
:提供全局访问点,使用双重检查锁定以确保线程安全,在需要时懒惰地创建单例实例。 -
互斥量:引入标准库中的
mutex
确保在多线程环境中的安全访问。 -
操作方法:定义了一个示例方法
operation()
,用于演示单例对象的使用。
六、模式总结
单例模式是一种常用的设计模式,在需要共享全局实例的场景下具有广泛的应用,包括由于其灵活性和控制实例数量的能力。因此,在适当场合应用单例模式能够提供很多的便利。与此同时,也需考虑到其对模块化测试以及维护的影响,因此在引入时需要注意设计的合理性和需求的明确性。适当应用单例模式可以有效提升系统的设计质量和访问性能。
没有回复内容