0.前言
今天做笔试遇到一个问答题,问简述一种设计模式的用法。鄙人才疏学浅,设计模式之类的高大上存在一直都是没怎么研究过,唯一一个用过的就是一个被众人唾弃的单例模式,不过要具体阐述单例模式怎么用,我只想到用于管理数据或者通用方法的类中使用。所以说一交卷就立马stack overflow了一波,下面总结一下。
1.一个简单的Singleton实现
之前实习的时候发现公司里面好多代码都有singleton,他们是这样实现的:
class singleton {
public:
static singleton* Instance();
private:
static singleton* instance_;
};
//singleton.cpp
singleton* singleton::instance_ = nullptr;
singleton* singleton::Instance() {
if (!instance_) {
instance_ = new singleton();
}
return instance_;
}
显然这是这里面内存泄露了,如果稍微改进一下,那么加个release方法来释放内存。其实完全不用这么麻烦,现代C++的singleton应该如下定义:
class testSingleton{
public:
~testSingleton(){}
testSingleton& operator=(const testSingleton& other)=delete;
testSingleton(const testSingleton& other)=delete;
static testSingleton& Instance(){
static testSingleton instance;
return instance;
}
private:
testSingleton(){}
};
1.为什么众高手纷纷唾弃Singleton
在看了几个高手的答案后,我发现他们其实并没有唾弃Singleton,而是在唾弃global state,为什么不直接唾弃global state而要绕个圈子去唾弃无辜的Singleton呢?很简单,因为大家都唾弃global state,你再唾弃就没人理你了,肯定要另辟蹊径才能让我们这些novice震惊不是。
2.使用Singleton(global)的坏处
1.因为单例代表着全局,而全局变量是transitive的,假设这样一个应用场景:我有个全局变量A,本来我写代码是设想A在我调用函数里使这个用时值为B,但是这个全局变量在另一个线程里被改成了C,结果就不对了。如果你的应用是单线程的话,那是不是也没什么事,当然这只是我的猜测。
2.使用单例会让代码变得难以阅读,这是对于维护者而言的
3.什么时候可以用SIngleton
1.根据上面所说,如果你的全局变量是immutable的,那么你使用单例来组织一下这些变量也没什么问题,因为其他代码不会改变他的值,只有它可以影响其他代码的执行,这是单向的。
2.如果你的单例产生的代码对于程序运行没有影响,那么你也可以使用Singleton,例如logger,你去掉它程序照跑,不会影响结果。
4.总结
其实高手们还说了不少,但是我功力不够都没怎么看懂,但是以上几点确实说的很有道理,以后再研究一下如何避免使用Singleton。