前言
《⼤话设计模式》⼀书中提到 24 种设计模式,但是目前阶段经常用到的就是单例模式和工厂模式,在此记录一下单例模式和工厂模式的特点,并附上C++代码实现。
设计模式还有6大原则,在这里就不赘述了,感觉太过于教条主义了,也记不住。
一、单例模式
特点: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。
在开发过程中,很多时候一个类我们希望它只创建一个对象,这个时候就需要用到单例模式了。
1.1 饿汉模式
饿汉模式就是在又一开始的时候类的对象就已经创建完成,方法是类里面包含一个静态方法。
该方法返回一个指向该类对象的指针,该方法是static公有的。
#include <mutex>
#include <iostream>
using namespace std;
/*
//饿汉模式
class SingleInstace{
public:
static SingleInstace* getInstance()
{
static SingleInstace instance;//注意是static的
return &instance;
}
//涉及到对象创建的函数都设为private的
private:
SingleInstace(){cout<<"这里是饿汉模式的构造函数"<<endl;}
SingleInstace(const SingleInstace& other){}
SingleInstace& operator=(const SingleInstace& other){return *this;}
};
int main()
{
//因为不能创建对象所以通过静态成员函数的⽅法返回静态成员变
SingleInstace* instance = SingleInstace::getInstance();
return 0;
}
1.2 懒汉模式
尽可能的晚的创建这个对象的实例,即在单例类第⼀次被引⽤的时候就将⾃⼰初始化。
代码如下:
#include <mutex>
#include <iostream>
using namespace std;
class SingleInstace{
public:
static SingleInstace* getInstance()
{
if(instance == nullptr)
{
m.lock();
instance = new SingleInstace();
m.unlock();
}
return instance;
}
//涉及到对象创建的函数都设为private的
private:
SingleInstace(){cout<<"这里是懒汉模式的构造函数"<<endl;}
SingleInstace(const SingleInstace& other){}
SingleInstace& operator=(const SingleInstace& other){return *this;}
static SingleInstace* instance;
static mutex m;
};
SingleInstace* SingleInstace::instance = nullptr;
mutex SingleInstace::m;//类中的static变量需要在外部定义初始化
int main()
{
//因为不能创建对象所以通过静态成员函数的⽅法返回静态成员变
SingleInstace* instance = SingleInstace::getInstance();
return 0;
}
单例模式的适⽤场景
-
系统只需要⼀个实例对象,或者考虑到资源消耗的太⼤⽽只允许创建⼀个对象。
-
客户调⽤类的单个实例只允许使用⼀个公共访问点,除了该访问点之外不允许通过其它
⽅式访问该实例(就是共有的静态⽅法)。
二、工厂模式
就是建⽴⼀个⼯⼚类,对实现了同⼀接⼝的⼀些类进⾏实例的创建。简单⼯⼚模式的实质是由⼀个⼯⼚类根据传⼊的参数,动态决定应该创建哪⼀个产品类(这些产品类继承⾃⼀个⽗类)的实例。
简单来说就是:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
下面是一个cpp代码示例:
#include <mutex>
#include <iostream>
using namespace std;
class Product{
public:
virtual void show() = 0;//纯虚函数
};
class ProductA : public Product{
public:
ProductA(){};
void show()
{
cout<<"这里是A"<<endl;
}
};
class ProductB : public Product{
public:
ProductB(){};
void show()
{
cout<<"这里是B"<<endl;
};
};
class Factory{
public:
Factory(){}
Product* product(string s)
{
if(s == "A")
return new ProductA();//如果之前的继承不写明是public的,这里就会报错
else if(s == "B")
return new ProductB();
return nullptr;
}
};
int main()
{
Factory factory;
Product* prod;
prod = factory.product("B");
prod->show();
prod = factory.product("A");
prod->show();
return 0;
}
⼯⼚模式⽬的就是代码解耦,如果我们不采⽤⼯⼚模式,如果要创建产品 A、B,通常做法采⽤ switch...case语句,那么想⼀想后期添加更多的产品进来,我们要添加更多的switch...case ,这样就很麻烦,⽽且也不符合设计模式中的开放封闭原则。