overview
创建型模式(侧重点是创建对象的方式灵活和可复用)里面有
1.工厂
2.抽象工厂
3.生成器
4.原型
5.单例
序
单例模式在实际的项目中是比较常见的(出于严格控制全局变量的考虑)。
单例模式的核心是不允许除自己类的特殊构建方法去创建自身类的对象。(可以通过修改获取实例的方法的代码去修改生成单例实例的个数,但是当我们谈论起单例,我们常常指只允许生成一个单例实例的单例模式)。
外观模式,享元模式,抽象工厂,生成器,原型都和单例模式有关联
1.具体例子-c++
备注:这个例子是典型单例模式:永远返回同一个单例实例的例子
这个例子里面的重点是class Sinleton类里面有一个指向自己的private静态指针,有一个std::mutex的private静态锁。这个静态指针在后面的具体实现中帮助确保永远回到同一个单例实例。这个锁帮助多线程安全使用单例实例。
需要被保护的数据可以放到protect里面,获取数据的接口则放到public里面。
为了让单例不允许除自己类的特殊构建方法去创建自身类的对象,要在public里面删掉默认的clone和assign符号。
在c++里面,类的静态变量和静态方法是在类的定义里面定义的,类的静态变量和静态方法是和类相关联的并不是和类的实例相关联的。使用类的静态变量和静态方法可以直接通过类名完成。
在类的静态方法中,无法直接访问非静态的,和类的实例直接关联的变量和方法。
/**
* The Singleton class defines the `GetInstance` method that serves as an
* alternative to constructor and lets clients access the same instance of this
* class over and over.
*/
class Singleton
{
/**
* The Singleton's constructor/destructor should always be private to
* prevent direct construction/desctruction calls with the `new`/`delete`
* operator.
*/
private:
static Singleton* pinstance_;
static std::mutex mutex_;
protected:
Singleton(const std::string value) : value_(value)
{
}
~Singleton() {}
std::string value_;
public:
/**
* Singletons should not be cloneable and should not be assignable
*/
Singleton(Singleton& other) = delete;
void operator=(const Singleton&) = delete;
/**
* This is the static method that controls the access to the singleton
* instance. On the first run, it creates a singleton object and places it
* into the static field. On subsequent runs, it returns the client existing
* object stored in the static field.
*/
static Singleton* GetInstance(const std::string& value);
void SomeBusinessLogic()
{
// ...
}
std::string GetValue() const {
return value_;
}
};
/**
* Static methods should be defined outside the class.
*/
Singleton* Singleton::pinstance_{ nullptr };
std::mutex Singleton::mutex_;
/**
* The first time we call GetInstance we will lock the storage location
* and then we make sure again that the variable is null and then we
* set the value. RU:
*/
Singleton* Singleton::GetInstance(const std::string& value)
{
std::lock_guard<std::mutex> lock(mutex_);
if (pinstance_ == nullptr)
{
pinstance_ = new Singleton(value);
}
return pinstance_;
}
void ThreadFoo() {
// Following code emulates slow initialization.
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
Singleton* singleton = Singleton::GetInstance("FOO");
std::cout << singleton->GetValue() << "\n";
}
void ThreadBar() {
// Following code emulates slow initialization.
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
Singleton* singleton = Singleton::GetInstance("BAR");
std::cout << singleton->GetValue() << "\n";
}
int singleton()
{
std::cout << "If you see the same value, then singleton was reused (yay!\n" <<
"If you see different values, then 2 singletons were created (booo!!)\n\n" <<
"RESULT:\n";
std::thread t1(ThreadFoo);
std::thread t2(ThreadBar);
t1.join();
t2.join();
return 0;
}