1.单例模式
应用
Logger日志模块,多个模块在使用我们日志类的时候都应该将日志写入同一个地方
Server类,创建和销毁的资源消耗代价非常大
ConnectionPool类,数据库连接池
可以确保一个类在全局范围内只能有一个实例,并且获取这个实例都是通过一个静态的全局访问结点。
饿汉式单例模式
在没调用类的全局访问结点之前 该对象就已经被创建了
静态成员变量需要在类内定义 类外初始化 且初始化时在main函数之前
肯定时线程安全的 因为他在main函数之前
#include <iostream>
using namespace std;
// 饿汉式单例模式 => 没访问全局访问结点之前 对象就已经被创建了 => 静态成员变量创建的
class hungryManSingleton
{
public:
static hungryManSingleton& getInstance()
{
return instance;
}
private:
hungryManSingleton() = default;
hungryManSingleton(const hungryManSingleton&) = delete;
hungryManSingleton& operator=(const hungryManSingleton&) = delete;
static hungryManSingleton instance;
};
hungryManSingleton hungryManSingleton::instance;
int main()
{
hungryManSingleton::getInstance();
}
懒汉式线程安全的单例
因为静态局部变量的初始化时线程安全的
#include <iostream>
using namespace std;
// 懒汉式线程安全的单例模式 => 静态局部变量的初始化式线程安全的
class lazyManSingletonMode
{
public:
static lazyManSingletonMode& getInstance()
{
static lazyManSingletonMode instance;
return instance;
}
private:
lazyManSingletonMode() = default;
lazyManSingletonMode(const lazyManSingletonMode&) = delete;
lazyManSingletonMode& operator=(const lazyManSingletonMode&) = delete;
};
int main()
{
lazyManSingletonMode::getInstance();
}
2.观察者模式
应用
Redis的发布-订阅功能 作为服务器的中间件
观察者-监听者模式 (发布-订阅模式)设计模式
行为型模式:主要关注的是对象之间的通信
设计模式
主要关注的是对象一对多的关系,也就是多个对象都依赖一个对象,当该对象发生改变的时候,其他的对象都能接收到相应的通知
#include <iostream>
#include <unordered_map>
#include <list>
using namespace std;
// 观察者抽象类
class Observer
{
public:
// 观察者所观察的事件发生了 => 调用该抽象接口
virtual void handler(int msgid) = 0; // 含有纯虚函数的类是抽象类
private:
};
// 第一个观察者实例
class Observer1 : public Observer
{
public:
void handler(int msgid)
{
switch (msgid)
{
case 1:
cout << "Observer1 recv 1 msg" << endl;
break;
case 2:
cout << "Observer1 recv 2 msg" << endl;
break;
default:
cout << "Observer1 recv unkonw msg!" << endl;
break;
}
}
private:
};
class Observer2 : public Observer
{
public:
void handler(int msgid)
{
switch (msgid)
{
case 2:
cout << "Observer2 recv 2 msg" << endl;
break;
default:
cout << "Observer2 recv unkonw msg!" << endl;
break;
}
}
private:
};
class Observer3 : public Observer
{
public:
void handler(int msgid)
{
switch (msgid)
{
case 1:
cout << "Observer3 recv 1 msg" << endl;
break;
case 3:
cout << "Observer3 recv 3 msg" << endl;
break;
default:
cout << "Observer3 recv unkonw msg!" << endl;
break;
}
}
private:
};
// 主题类
class Subject
{
public:
// 给主题增加观察者对象
void addSubjectMap(Observer* observer, int msgid)
{
auto it = _subjectMap.find(msgid);
if(it != _subjectMap.end())
{
it->second.push_back(observer);
}
else
{
list<Observer*> lis;
lis.push_back(observer);
_subjectMap.insert({msgid, lis});
}
}
// 主题检测发生改变 通知相应的观察者对象处理事件
void dispatch(int msgid)
{
auto it = _subjectMap.find(msgid);
if(it != _subjectMap.end())
{
for(Observer* pObser : it->second)
{
pObser->handler(msgid);
}
}
}
private:
unordered_map<int, list<Observer*>> _subjectMap;
};
int main()
{
Subject subject;
Observer *p1 = new Observer1();
Observer *p2 = new Observer2();
Observer *p3 = new Observer3();
subject.addSubjectMap(p1, 1);
subject.addSubjectMap(p1, 2);
subject.addSubjectMap(p2, 2);
subject.addSubjectMap(p3, 1);
subject.addSubjectMap(p3, 3);
int msgid = 0;
while(1)
{
cout << "输入消息id:";
cin >> msgid;
if(msgid == -1) break;
subject.dispatch(msgid);
}
return 0;
}
3.抽象工厂模式
#include <iostream>
#include <string>
#include <memory>
using namespace std;
// 产品1:抽象Car类
class Car
{
public:
Car(string name) : _name(name) { }
virtual void show() = 0;
virtual ~Car() = default;
protected:
string _name;
};
class Bmw : public Car
{
public:
Bmw(string name) : Car(name) { }
void show()
{
cout << "生产一辆宝马汽车:" << _name << endl;
}
};
class Audi : public Car
{
public:
Audi(string name) : Car(name) { }
void show()
{
cout << "生产一辆奥迪汽车:" << _name << endl;
}
};
// 产品2:抽象车灯类
class CarLight
{
public:
virtual void show() = 0;
virtual ~CarLight() = default;
};
class BmwLight : public CarLight
{
public:
void show()
{
cout << "生产了一盏宝马汽车的灯" << endl;
}
};
class AudiLight : public CarLight
{
public:
void show()
{
cout << "生产了一盏奥迪汽车的灯" << endl;
}
};
// 抽象工厂里面 => 提供多个产品创建的接口 => 汽车工厂 => 车灯 + 车框架 + 车雨伞 等等
class AbstractFactory
{
public:
virtual Car* createCar(string name) = 0;
virtual CarLight* createCarLight() = 0;
virtual ~AbstractFactory() = default;
};
// 一个工厂中 创建 一系列有管理关系的产品
class BmwFactory : public AbstractFactory
{
public:
Car* createCar(string name)
{
return new Bmw(name);
}
CarLight* createCarLight()
{
return new BmwLight();
}
};
class AudiFactory : public AbstractFactory
{
public:
Car* createCar(string name)
{
return new Audi(name);
}
CarLight* createCarLight()
{
return new AudiLight();
}
};
int main()
{
unique_ptr<AbstractFactory> bmwFactory(new BmwFactory());
unique_ptr<AbstractFactory> audiFactory(new AudiFactory());
unique_ptr<Car> pcar1(bmwFactory->createCar("7系"));
unique_ptr<CarLight> pl1(bmwFactory->createCarLight());
unique_ptr<Car> pcar2(audiFactory->createCar("A6"));
unique_ptr<CarLight> pl2(audiFactory->createCarLight());
pcar1->show();
pl1->show();
pcar2->show();
pl2->show();
return 0;
}
4.代理模式
#include <iostream>
#include <memory>
using namespace std;
// 抽象类视频网站
class AbstractVideoSite
{
public:
// 免费电影抽象接口
virtual void freeVideo() = 0;
// vip电影抽象接口
virtual void vipVideo() = 0;
// svip电影抽象接口
virtual void svipVideo() = 0;
};
// 委托类
class QIYVideostie : public AbstractVideoSite
{
public:
virtual void freeVideo()
{
cout << "可以观看免费电影" << endl;
}
virtual void vipVideo()
{
cout << "可以观看vip电影" << endl;
}
virtual void svipVideo()
{
cout << "可以观看svip电影" << endl;
}
};
// 爱奇艺免费用户观看电影的代理类
class FreeVideoProxy : public AbstractVideoSite
{
public:
FreeVideoProxy()
{
pVideo = new QIYVideostie();
}
~FreeVideoProxy()
{
delete pVideo;
}
virtual void freeVideo()
{
pVideo->freeVideo();
}
virtual void vipVideo()
{
cout << "您只是普通用户 无法观看VIP电影" << endl;
}
virtual void svipVideo()
{
cout << "您只是普通用户 无法观看SVIP电影" << endl;
}
private:
AbstractVideoSite* pVideo;
};
// 爱奇艺VIP用户观看电影的代理类
class VipVideoProxy : public AbstractVideoSite
{
public:
VipVideoProxy()
{
pVideo = new QIYVideostie();
}
~VipVideoProxy()
{
delete pVideo;
}
virtual void freeVideo()
{
pVideo->freeVideo();
}
virtual void vipVideo()
{
pVideo->vipVideo();
}
virtual void svipVideo()
{
cout << "您只是vip 无法观看SVIP电影" << endl;
}
private:
AbstractVideoSite* pVideo;
};
// 爱奇艺SVIP用户观看电影的代理类
class SvipVideoProxy : public AbstractVideoSite
{
public:
SvipVideoProxy()
{
pVideo = new QIYVideostie();
}
~SvipVideoProxy()
{
delete pVideo;
}
virtual void freeVideo()
{
pVideo->freeVideo();
}
virtual void vipVideo()
{
pVideo->vipVideo();
}
virtual void svipVideo()
{
pVideo->svipVideo();
}
private:
AbstractVideoSite* pVideo;
};
void watchVideo(unique_ptr<AbstractVideoSite>&& pQIY)
{
pQIY->freeVideo();
pQIY->vipVideo();
pQIY->svipVideo();
}
int main()
{
unique_ptr<AbstractVideoSite> pQIYfreeUser(new FreeVideoProxy());
watchVideo(std::move(pQIYfreeUser));
cout << "--------------------------------------" << endl;
unique_ptr<AbstractVideoSite> pQIYvipUser(new VipVideoProxy());
watchVideo(std::move(pQIYvipUser));
cout << "--------------------------------------" << endl;
unique_ptr<AbstractVideoSite> pQIYsvipUser(new SvipVideoProxy());
watchVideo(std::move(pQIYsvipUser));
return 0;
}
5.适配器模式
解决接口不兼容问题
进行代码的重构
增加一个适配器类 进行接口的转接
#include <iostream>
using namespace std;
class HDMI
{
public:
virtual void play() = 0;
};
class Typec
{
public:
virtual void play() = 0;
};
class TV_HDMI : public HDMI
{
public:
void play()
{
cout << "通过HDMI接口连接投影仪 进行视频播放" << endl;
}
};
class Computer
{
public:
void playVideo(Typec *typec)
{
typec->play();
}
};
class HDMItoTypecAdapter : public Typec
{
public:
HDMItoTypecAdapter(HDMI *p)
{
phdmi = p;
}
void play()
{
phdmi->play();
}
private:
HDMI *phdmi;
};
int main()
{
Computer *pcomp = new Computer();
pcomp->playVideo(new HDMItoTypecAdapter(new TV_HDMI));
return 0;
}
6.装饰器模式
作用
为现有类增加一些新的功能
#include <iostream>
#include <memory>
using namespace std;
class Car
{
public:
virtual void show() =0;
};
class Bmw : public Car
{
public:
void show()
{
cout << "这是一辆宝马汽车" << endl;
}
};
class Audi : public Car
{
public:
void show()
{
cout << "这是一辆奔驰汽车" << endl;
}
};
class Decorator : Car
{
public:
Decorator(Car* p) : pcar(p) {}
void show()
{
cout << "增加定速巡航功能" << endl;
cout << "增加自动刹车功能" << endl;
pcar->show();
}
private:
Car* pcar;
};
int main()
{
unique_ptr<Decorator> pdecor(new Decorator(new Audi()));
pdecor->show();
return 0;
}