一、设计模式是什么?
设计模式是指在软件开发中,经过验证的,用于解决在特定环境下,重复出现的,特定问题的解决方案。
二、设计模式有哪些?
1. 观察者模式
定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
1.1. 背景
气象站发布气象资料给数据中心,数据中心经过处理,将气象信息更新到多个不同的显示终端(A 、B、C)。
1.2. 伪代码
cpp
#include <list>
#include <algorithm>
#include <iostream>
using namespace std;
//
class IDisplay {
public:
virtual void Show(float temperature) = 0;
virtual ~IDisplay() {}
};
class DisplayA : public IDisplay {
public:
virtual void Show(float temperature) {
cout << "DisplayA Show" << endl;
}
};
class DisplayB : public IDisplay{
public:
virtual void Show(float temperature) {
cout << "DisplayB Show" << endl;
}
};
class DisplayC : public IDisplay{
public:
virtual void Show(float temperature) {
cout << "DisplayC Show" << endl;
}
};
class DisplayD : public IDisplay{
public:
virtual void Show(float temperature) {
cout << "DisplayC Show" << endl;
}
};
class WeatherData {
};
class DataCenter {
public:
void Attach(IDisplay * ob) {
obs.emplace_back(ob);
}
void Detach(IDisplay * ob) {
if(obs.empty()){
return;
}
for(auto it = obs.begin(); it != obs.end(); ++it){
if(*it == ob){
obs.erase(it);
return;
}
}
}
void Notify() {
float temper = CalcTemperature();
for (auto iter : obs) {
iter->Show(temper);
}
}
// 接口隔离
private:
WeatherData * GetWeatherData();
float CalcTemperature() {
WeatherData * data = GetWeatherData();
// ...
float temper/* = */;
return temper;
}
std::list<IDisplay*> obs;
};
int main() {
// 单例模式
DataCenter *center = new DataCenter;
// ... 某个模块
IDisplay *da = new DisplayA();
center->Attach(da);
// ...
IDisplay *db = new DisplayB();
center->Attach(db);
IDisplay *dc = new DisplayC();
center->Attach(dc);
center->Notify();
//-----
center->Detach(db);
center->Notify();
//....
center->Attach(dd);
center->Notify();
return 0;
}
2. 策略模式
定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户程序而变化。
2.1 背景
某商场节假日有固定促销活动,为了加大促销力度,现提升国庆节促销活动规格;
2.2 伪代码
cpp
class Context {
};
class ProStategy {
public:
virtual double CalcPro(const Context &ctx) = 0;
virtual ~ProStategy();
};
class VAC_Spring : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class VAC_QiXi : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class VAC_QiXi1 : public VAC_QiXi {
public:
virtual double CalcPro(const Context &ctx){}
};
class VAC_Wuyi : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class VAC_GuoQing : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class VAC_Shengdan : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class Promotion {
public:
Promotion(ProStategy *sss) : s(sss){}
~Promotion(){}
double CalcPromotion(const Context &ctx){
return s->CalcPro(ctx);
}
private:
ProStategy *s;
};
int main () {
Context ctx;
ProStategy *s = new VAC_QiXi1();
Promotion *p = new Promotion(s);
p->CalcPromotion(ctx);
return 0;
}
3. 单例模式
保证一个类仅有一个实例,并提供一个该实例的全局访问点。
3.1 代码实现
版本一
cpp
#include <bits/stdc++.h>
class Singleton
{
public:
static Singleton *getInstance()
{
if (nullptr == _instance)
{
_instance = new Singleton();
}
return _instance;
}
private:
Singleton() {}
~Singleton() {}
Singleton(const Singelton &) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton(Singleton &&) == delete;
Singleton &operator=(Singleton &&) = delete;
private:
static Singleton *_instance;
};
Singleton *Singleton::_instance = nullptr;
版本二
cpp
#include <bits/stdc++.h>
class Singleton
{
public:
static Singleton *getInstance()
{
if (nullptr == _instance)
{
_instance = new Singleton();
atexit(destroy); // 存在线程安全问题
}
return _instance;
}
private:
static void destroy()
{
if (_instance)
{
delete _instance;
_instance = nullptr;
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singelton &) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton(Singleton &&) == delete;
Singleton &operator=(Singleton &&) = delete;
private:
static Singleton *_instance;
};
Singleton *Singleton::_instance = nullptr;
版本三饿汉模式 解决线程不安全
cpp
#include <bits/stdc++.h>
class Singleton
{
public:
static Singleton *getInstance()
{
if (nullptr == _instance)
{
_instance = new Singleton();
atexit(destroy); // 存在线程安全问题
}
return _instance;
}
private:
static void destroy()
{
if (_instance)
{
delete _instance;
_instance = nullptr;
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singelton &) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton(Singleton &&) == delete;
Singleton &operator=(Singleton &&) = delete;
private:
static Singleton *_instance;
};
Singleton *Singleton::_instance = Singleton::getinstance(); //饿汉模式
版本四 懒汉模式(饱汉模式)加锁解决线程不安全
cpp
#include <bits/stdc++.h>
class Singleton
{
public:
static Singleton *getInstance()
{
std::lock_guard<std::mutex> lock(_mutex); //加锁
if (nullptr == _instance)
{
_instance = new Singleton();
atexit(destroy);
}
return _instance;
}
private:
static void destroy()
{
if (_instance)
{
delete _instance;
_instance = nullptr;
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singelton &) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton(Singleton &&) == delete;
Singleton &operator=(Singleton &&) = delete;
private:
static Singleton *_instance;
static std::mutex _mutex;
};
Singleton *Singleton::_instance = nullptr; //懒汉模式
std::mutex Singleton::_mutex;