文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。
资料仅供学习交流使用。
作者:Aliven888
文章目录
1、背景
1.1、为什么要学习设计模式
设计模式是一种知识和经验,和编程语言无关。熟练的掌握各种设计模式后,我们(程序猿)可以快速的去识别一个系统的骨骼框架,也可以快速的搭建出一个健壮的系统。
设计模式也可以理解为我们(程序猿)心中的一张张蓝图,握住他们,就可能成为一位有大局观的构架师,松开它们,可能注定只能成为一名默默无闻 的码农。
1.2、什么是单例模式
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式,,可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
如果希望在系统中某个类的对象只存在一个,单例模式显然是最好的解决方案。
1.3、单例模式的特点
1、某个类只有一个实例(并非绝对,一些特殊的情况下可以存在多个)。
2、它必须自行创建这个实例。
3、它必须向整个系统提供这个实例(即整个系统都可以直接使用该实例)。
1.4、使用场景
1、日志打印:每一个软件系统都会存在一个日志打印功能,而且在软件系统中很多位置都在调用该打印功能,此时为了保证日志文件的安全写入,可以使用单例模式实现。
2、设备管理系统:在设备管理系统中,不管有多少个设备,那么设备的管理类就只会存在一个。
1.5、单例模式的实现思路
要求类只能返回同一个对象的引用,和一个获取给对象的方法。
单例模式的实现主要分为以下两个步骤:
1、将该类的构造方法定义为私有方法,这样其他的代码就无法调用该构造函数去实例化新的对象了。
2、该类提供一个静态的方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,否则就先创建,然后再返回。
1.6、单例模式的UML:
1.7、单例模式常用的实现方式
1、懒汉模式
2、线程安全模式
3、饿汉模式
2、单例模式常用模式介绍
2.1、懒汉模式
定义: 懒汉,顾名思义,就是很懒,不到使用的时候,是不会想起来去实例化它的。也就是说在第一次使用到类实例的时候才回去实例化。
特点: 以空间换时间,是非线程安全的。
懒汉模式代码演示:
//.h
class CSingletonPattern
{
public:
static CSingletonPattern *getInstance(); //创建实例对象接口函数
void DestoryInstance(); //销毁实例对象接口函数
~CSingletonPattern();
private:
CSingletonPattern();
private:
static CSingletonPattern *m_instance;
};
//.cpp
CSingletonPattern::CSingletonPattern()
{
}
CSingletonPattern::~CSingletonPattern()
{
//销毁对象
DestoryInstance();
}
//初始化对象
CSingletonPattern *CSingletonPattern::m_instance = NULL;
//创建实例对象
CSingletonPattern* CSingletonPattern::getInstance()
{
//对象不为空,则创建对象
if (NULL == m_instance)
{
m_instance = new CSingletonPattern();
}
return m_instance;
}
void CSingletonPattern::DestoryInstance() //销毁实例对象
{
delete m_instance;
m_instance = NULL;
}
2.2、线程安全模式
我们前面说懒汉模式在线程上是不安全的,那我要怎么实现呢?
相比想到这里就行明白了,既然线程资源不安全,那么我们就加个线程锁控制一下如何。
代码演示:
//.h
class CSingletonPattern
{
public:
static CSingletonPattern *getInstance(); //创建实例对象
void DestoryInstance(); //销毁实例对象
~CSingletonPattern();
private:
CSingletonPattern();
private:
static CSingletonPattern *m_instance;
static mutex m_mutex; //定义互斥锁
};
//.cpp
CSingletonPattern::CSingletonPattern()
{
}
CSingletonPattern::~CSingletonPattern()
{
DestoryInstance();
}
//初始化对象
CSingletonPattern *CSingletonPattern::m_instance = NULL;
mutex CSingletonPattern::m_mutex;
CSingletonPattern* CSingletonPattern::getInstance() //创建实例对象
{
//对象不为空,则创建对象
if (NULL == m_instance)
{
m_mutex.lock();
//这个为了防止在加锁的过程中,系统中的两个位置同时调用,这里需要在判断一次
//以保证加锁成功后进来的只有一个位置调用。
if(NULL == m_instance)
{
m_instance = new CSingletonPattern();
}
m_mutex.unlock();
}
return m_instance;
}
void CSingletonPattern::DestoryInstance() //销毁实例对象
{
delete m_instance;
m_instance = NULL;
}
2.3、饿汉模式
定义: 顾名思义,饿的时候才会饥不择食。在系统启动时,对象就被实例化创建。
特点: 以空间换时间,是线程安全的。
//.h
class CSingletonPattern
{
public:
static CSingletonPattern *getInstance(); //创建实例对象接口函数
void DestoryInstance(); //销毁实例对象接口函数
~CSingletonPattern();
private:
CSingletonPattern();
private:
static CSingletonPattern *m_instance;
};
//.cpp
CSingletonPattern::CSingletonPattern()
{
}
CSingletonPattern::~CSingletonPattern()
{
//销毁对象
DestoryInstance();
}
//初始化对象
CSingletonPattern *CSingletonPattern::m_instance = new CSingletonPattern();
//获取实例对象
CSingletonPattern* CSingletonPattern::getInstance()
{
return m_instance;
}
void CSingletonPattern::DestoryInstance() //销毁实例对象
{
delete m_instance;
m_instance = NULL;
}
2.4、优缺点对比
1、懒汉方式:在访问量较少的情况下使用,以时间换空间,但是线程不安全。
2、饿汉方式:在访问量较多的情况下使用,以空间换时间,线程安全;
3、饿汉方式反而是最懒的。