设计模式是在软件工程中广泛应用的解决特定问题的通用可重用解决方案。它们提供了一种在软件设计中通用的、经过验证的方法。设计模式有助于解决面临的各种设计问题,并且已被证明在不同的应用场景下是有效的。
单例模式确保一个类只有一个实例,并提供了一个全局访问点,这在许多软件设计中都是很有用的。这种模式通常在需要控制资源访问、限制对象创建、或者需要跨多个部分共享状态时使用。
在实现单例模式时,通常需要注意以下几点:
私有构造函数:确保外部无法直接实例化对象,只能通过提供的访问方法获取实例。
静态方法或静态变量:提供全局访问点。通常是一个静态方法来获取单例实例,或者是一个静态变量来保存单例实例。
延迟实例化:有时候,单例对象不需要在程序启动时立即创建,可以在需要时才创建。这样可以节省资源,提高性能。
线程安全性:在多线程环境下,确保单例对象的创建是线程安全的,避免出现竞态条件或多次实例化的情况。
序列化和反序列化:如果单例类需要支持序列化和反序列化,需要特别注意如何保持单例特性。
当谈到单例模式时,可以通过懒汉模式(Lazy Singleton)和饿汉模式(Eager Singleton)来实现。懒汉模式是在需要时才创建实例,而饿汉模式是在程序启动时就创建实例。
懒汉模式
#include <iostream>
class LazySingleton {
private:
static LazySingleton* instance;
LazySingleton() {} // 私有构造函数
public:
// 提供全局访问点
static LazySingleton* getInstance() {
if (!instance) {
instance = new LazySingleton();
}
return instance;
}
};
LazySingleton* LazySingleton::instance = nullptr; // 初始化为 nullptr
int main() {
LazySingleton* lazyInstance1 = LazySingleton::getInstance();
LazySingleton* lazyInstance2 = LazySingleton::getInstance();
std::cout << "lazyInstance1 address: " << lazyInstance1 << std::endl;
std::cout << "lazyInstance2 address: " << lazyInstance2 << std::endl;
return 0;
}
饿汉模式
#include <iostream>
class EagerSingleton {
private:
static EagerSingleton* instance;
EagerSingleton() {} // 私有构造函数
public:
// 在程序启动时就创建实例
static EagerSingleton* getInstance() {
return instance;
}
};
// 在定义时就初始化实例
EagerSingleton* EagerSingleton::instance = new EagerSingleton();
int main() {
EagerSingleton* eagerInstance1 = EagerSingleton::getInstance();
EagerSingleton* eagerInstance2 = EagerSingleton::getInstance();
std::cout << "eagerInstance1 address: " << eagerInstance1 << std::endl;
std::cout << "eagerInstance2 address: " << eagerInstance2 << std::endl;
return 0;
}
这两种模式的区别是,懒汉模式在 getInstance() 方法中检查了实例是否存在,如果不存在则创建新的实例。而饿汉模式则在定义时就创建了实例,因此不需要在 getInstance() 方法中进行检查。