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;
}