虽然说“架构”是大智慧,“设计模式”是小聪明。但是很多时候,我们在代码中体现的小聪明,也能够让程序变得耦合性强,可读性高,复用性好。在本期,我们来一起通过实实在在的代码,学习下几种在软件开发过程中使用的“设计模式”。
1 . 单 例 模 式(C++为例)
顾名思义,只有一个例子,就是说,在核心的程序里,只有一个被成为单例的特殊类,保证在程序中,应用这种类只有一个对象。因为在某些情况下,我们确实只需要一个对象,否则会导致资源浪费。比如:任务管理器、文件系统、记时系统等等。那么,单例模式该怎么实现呢···
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
// 单 例 模 式
class Example {
private:
Example();
~Example();
static Example* m_Instance;
public:
static Example* GetInstance();
};
Example::Example(){
}
Example::~Example(){
free(m_Instance);
}
Example* Example::GetInstance(){
if (m_Instance == NULL) {
m_Instance = new Example();
}
return m_Instance;
}
int main() {
// 1 ( 在GetInstance函数中需要new一个Example类型的变量m_Instance )
Example *ex1 = Example::GetInstance();
// 2( 在GetInstance函数中不需要new一个Example类型的变量m_Instance )
Example *ex2 = Example::GetInstance();
std::cout << std::endl;
}
以上的代码,就是以C++为例写的一个基本的单利模式。但是,我们在多线程中使用到Excample这个类,类中的m_Instance变量可能会被多个线程使用,如果资源被其中一个线程占用,而其他的线程继续访问变量资源,原则上不会导致程序死机,但是会给程序带来不可控的、逻辑上的问题。因此,需要这样修改:
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
// 单 例 模 式
#include <mutex>
class Example {
private:
Example();
~Example();
static Example* m_Instance;
// 加锁
static std::mutex* m_Mutex;
public:
static Example* GetInstance();
};
Example::Example(){
//m_Mutex = new std::mutex();
}
Example::~Example(){
if (m_Instance != NULL)
delete m_Instance;
}
std::mutex* Example::m_Mutex = NULL;
Example* Example::m_Instance = NULL;
Example* Example::GetInstance(){
if (m_Instance == NULL) {
m_Mutex->lock();
if (m_Instance == NULL) {
m_Instance = new Example();
}
m_Mutex->unlock();
}
return m_Instance;
}
int main() {
// 1 ( 在GetInstance函数中需要new一个Example类型的变量m_Instance )
Example *ex1 = Example::GetInstance();
// 2( 在GetInstance函数中不需要new一个Example类型的变量m_Instance )
Example *ex2 = Example::GetInstance();
std::cout << std::endl;
}
给GetInstance函数增加了加锁,但是我们在这里做了优化,只需要在m_Instance为空的情况下,进行加锁,不为空的情况下,不需要加锁,提升效率。
2 . 工 厂 模 式(以C++为例)
工厂模式有好几类,我们从简单到复杂来看。顾名思义,工厂模式是以工厂生产的方式,给你输出类的对象。我们先来看看简单工厂模式:
比如现在有这么一个问题:我有一个制造笔记本电脑的工厂,现在要生产一批笔记本电脑,但是我并不知道我要生产什么品牌的笔记本,可能有好几种品牌。那么怎么办呢?当然了,我们首先想到的是,你要什么笔记本,我给你制造(new)笔记本,建立不同的对象,也就是说,你要多少,我new多少,随着笔记本品牌的增多,new操作也越来越多,导致后期维护十分麻烦,同时造成其他的软件开发人员不明白对象的含义。再者,加上new出来的对象后边需要跟上一长串的异常处理的代码,导致代码臃肿,可读性,可靠性,延展性不强。因此,我们需要新建一个类,专门来管理各种不同对象的建立和释放。于是:
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
// 简 单 工 厂 模 式
/*
Notebook类:笔记本电脑的基类(抽象类)
*/
class Notebook{
public:
Notebook();
~Notebook();
public:
virtual void CreateObject() = 0; // 纯虚函数,由派生类来实现
};
Notebook::Notebook() {
}
Notebook::~Notebook() {
}
// Mac 派生类
class Mac : public Notebook {
public:
Mac();
~Mac();
public:
void CreateObject() {
std::cout << "i'm Mac." << std::endl;
}
};
Mac::Mac() {
}
Mac::~Mac() {
}
// SurfaceBook 派生类
class SurfaceBook : public Notebook {
public:
SurfaceBook();
~SurfaceBook();
public:
void CreateObject() {
std::cout << "i'm Surface book." << std::endl;
}
};
SurfaceBook::SurfaceBook() {
}
SurfaceBook::~SurfaceBook() {
}
// HuaWeiBook 派生类
class HuaWeiBook : public Notebook {
public:
HuaWeiBook();
~HuaWeiBook();
public:
void CreateObject() {
std::cout << "i'm HuaWei book." << std::endl;
}
};
HuaWeiBook::HuaWeiBook() {
}
HuaWeiBook::~HuaWeiBook() {
}
/*
Factory 类的作用主要是来个管理不同类的对象的建立和释放
*/
enum BookType {
Macbooks,
Surfacebooks,
Huaweibooks
};
class Factory
{
public:
Factory();
~Factory();
public:
Notebook* CreateBook(BookType Types);
};
Factory::Factory(){
}
// 工厂类的核心代码
Notebook* Factory::CreateBook(BookType Types) {
switch (Types){
case BookType::Macbooks:
return new Mac();
break;
case BookType::Surfacebooks:
return new SurfaceBook();
break;
case BookType::Huaweibooks:
return new HuaWeiBook();
break;
default:
break;
}
return NULL;
}
Factory::~Factory(){
}
int main() {
// 创建管理类
Factory *m_Factory = new Factory();
// 按需创建
Notebook *object1 = m_Factory->CreateBook(BookType::Macbooks);
Notebook *object2 = m_Factory->CreateBook(BookType::Surfacebooks);
Notebook *object3 = m_Factory->CreateBook(BookType::Huaweibooks);
// 输出看看
object1->CreateObject();
object2->CreateObject();
object3->CreateObject();
std::cin.get();
}
输出的结果是:
我们在Demo程序中,建立了一个Factory类,用来管理其它的类(NoteBook、Mac、SurfaceBook、HuaWeiBook等),根据需求,通过“多态”创建出不同的类。
工厂模式还有工厂方法模式、抽象工厂模式等。剩余的,在接下来的博文中详细描述。未完,待续。