前言
尊重原创,本系列文本解析部分主要基于Candidate for Master’s Degree School of Computer Wuhan University的K_Eckel([email protected])《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》。为了避免重造轮子,本系列博文对源码在ubuntu16.04下做了验证并上传到了gitee,再次感谢。
如有问题,可邮件联系我([email protected])并共同探讨解决方案。
目录
创建型模式(Creating Pattern)
Factory 模式 | AbstactFactory 模式 | Singleton 模式 | Builder 模式 | Prototype 模式
结构型模式(Structrual Pattern)
Bridge 模式 | Adapter 模式 | Decorator 模式 | Composite 模式 | Flyweight 模式 | Facade 模式 | Proxy 模式
行为型模式(Behavioral Pattern)
Template 模式 | Strategy 模式 | State 模式 | Observer 模式 | Memento 模式 | Mediator 模式 | Command 模式 | Visitor 模式 | Iterator 模式 | Interpreter 模式 | Chain of Responsibility 模式
Singleton模式简介:
单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出,GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘。
单例模式有许多种实现方法,在C++中,甚至可以直接用一个全局变量做到这一点,但这样的代码显的很不优雅。 使用全局对象能够保证方便地访问实例,但是不能保证只声明一个对象——也就是说除了一个全局实例外,仍然能创建相同类的本地实例。《设计模式》一书中给出了一种很不错的实现,定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。
单例模式通过类本身来管理其唯一实例,这种特性提供了解决问题的方法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全局访问。唯一实例类Singleton在静态成员函数中隐藏创建实例的操作。习惯上把这个成员函数叫做Instance(),它的返回值是唯一实例的指针。
问题
Singleton 模式解决问题十分常见,我们怎样去创建一个唯一的变量(对象)?在基于对象的设计中我们可以通过创建一个全局变量(对象)来实现,在面向对象和面向过程结合的设计范式(如 C++中)中,我们也还是可以通过一个全局变量实现这一点。但是当我们遇到了纯粹的面向对象范式中,这一点可能就只能是通过 Singleton 模式来实现了,可能这也正是很多公司在招聘 Java 开发人员时候经常考察 Singleton 模式的缘故吧。
Singleton 模式在开发中非常有用,具体使用在讨论给出。
模式选择
Singleton 模式典型的结构图为:
图 1:Singleton Pattern 结构图
在 Singleton 模式的结构图中可以看到,我们通过维护一个 static
的成员变量来记录这个唯一的对象实例。通过提供一个 staitc
的接口 instance
来获得这个唯一的实例。
实现
完整代码示例(code)
Singleton 模式的实现比较简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 Visual Studio Code,Version: 1.36.1 下测试运行)。
源码gitee地址:点击这里
代码目录结构:
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/Singleton/src$ tree ../
../
├── include
│ └── Singleton.h
└── src
├── main.cpp
└── Singleton.cpp
2 directories, 3 files
Singleton.h:
// Singleton.h
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <iostream>
using namespace std;
class Singleton {
private:
static Singleton* _instance;
protected:
Singleton(/* args */);
public:
~Singleton();
static Singleton* Instance();
};
#endif //~_SINGLETON_H_
Singleton.cpp:
//Singleton.cpp
#include "../include/Singleton.h"
#include <iostream>
using namespace std;
Singleton* Singleton::_instance = 0;
Singleton::Singleton(){
printf("Singleton.... \n");
}
Singleton* Singleton::Instance(){
if (_instance == 0){
_instance = new Singleton();
}
return _instance;
}
main.cpp:
// main.cpp
#include <iostream>
#include "../include/Singleton.h"
using namespace std;
int main(int argc, char* argv[]) {
Singleton* sgn = Singleton::Instance();
return 0;
}
代码说明
Singleton 模式的实现无须补充解释,需要说明的是,Singleton 不可以被实例化,因此我们将其构造函数声明为 protected
或者直接声明为 private
。
编译运行结果:
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/Singleton/src$ g++ *.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/Singleton/src$ ./a.out
Singleton....
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/Singleton/src$
讨论
Singleton 模式在开发中经常用到,且不说我们开发过程中一些变量必须是唯一的,比如说打印机的实例等等。
Singleton 模式经常和 Factory(AbstractFactory)模式在一起使用,因为系统中工厂对象一般来说只要一个,笔者在开发 Visual CMCS 的时候,语义分析过程(以及其他过程)中都用到工厂模式来创建对象(对象实在是太多了),这里的工厂对象实现就是同时是一个Singleton 模式的实例,因为系统我们就只要一个工厂来创建对象就可以了。