单例模式
一个类不论创建多少次对象,永远只能得到该类型一个对象的实例
//饿汉式单例模式
class Singleton {
public:
static Singleton* getInstance() {
return &instance;
}
private:
static Singleton instance;//2.定义一个唯一的实例对象
Singleton(){} //1.构造函数私有化
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton Singleton::instance;//类内的静态变量,类外初始化
int mian() {
Singleton* p1 = Singleton::getInstance();
Singleton* p2 = Singleton::getInstance();
return 0;
}
-
饿汉式一定是线程安全的,对象的实例化是静态的处于数据段,在程序运行之前就已经初始化好了,但是懒汉式更通用,没有资源浪费
懒汉式
对象的实例化延迟到第一次调用getInstance()
class Singleton {
public:
static Singleton* getInstance() {//是一个可重入函数(函数未执行完成,还能不能重新调用),线程不安全
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
private:
static Singleton* instance;//2.定义一个唯一的实例对象
Singleton() {} //1.构造函数私有化
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::instance = nullptr;//类内的静态变量,类外初始化
线程安全
mutex mtx;
class Singleton {
public:
static Singleton* getInstance() {
/*//下面方法一
if (instance == nullptr) {
lock_guard<mutex> gurad(mtx);
instance = new Singleton();
}
return instance;*/
//方法二,局部静态变量的初始化,的汇编指令是多线程安全的
static Singleton instance;
return &instance;
}
private:
static Singleton* volatile instance;//2.定义一个唯一的实例对象
Singleton() {} //1.构造函数私有化
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton* volatile Singleton::instance = nullptr;//类内的静态变量,类外初始化
所有的getInstance()都是static是因为不需要实例化对象,就能直接获取单例
工厂模式
主要封装了对象的创建
简单工厂
使用一个类,简单的根据参数,调用new来构造对象
class SimpleFactory {
public:
Car* createCar(CarType ct) {
switch (ct) {
case BMW:
return new Bmw("x1");
case AUDO:
return new Audo("x1");
default:
cerr << "error" << endl;
break;
}
return nullptr;
}
};
工厂方法
每需要一个产品,那就有一个工厂类,过于精细,类太多
class Factory {
public:
virtual Car* createCar(string name) = 0;
};
class BMWFactory :public Factory {
public:
Car* createCar(string name) {
return new Bmw(name);
}
};
class AUDOFactory :public Factory {
public:
Car* createCar(string name) {
return new Audo(name);
}
};
抽象工厂
一系列的产品,放在一个工厂里面完成
class AbstractFactory {
public:
virtual Car* createCar(string name) = 0;
virtual Light* createLight() = 0;
};
class BMWFactory :public AbstractFactory {
public:
Car* createCar(string name) {
return new Bmw(name);
}
Light* createLight() {
return new BmwLight;
}
};
class AUDOFactory :public AbstractFactory {
public:
Car* createCar(string name) {
return new Audo(name);
}
Light* createLight() {
return new AudoLight;
}
};
代理模式
通过代理类,来控制实际对象的访问权限
对于不同的权限,声明不同的代理类,代理类和被代理类继承统一基类,
class VideoSite {
public:
virtual void freeMovie() = 0;
virtual void vipMovoe() = 0;
virtual void ticketMovie() = 0;
};
//被代理类
class FixBugVideoSite :public VideoSite {
public:
virtual void freeMovie() {
cout << "watch FreeMovie" << endl;
}
virtual void vipMovoe() {
cout << "watch VipMovie" << endl;
}
virtual void ticketMovie() {
cout << "watch ticketMovie" << endl;
}
};
//代理类
class Proxyfree : public VideoSite {
public:
Proxyfree() {
pVideo = new FixBugVideoSite();
}
~Proxyfree() {
delete pVideo;
}
virtual void freeMovie() {
pVideo->freeMovie();//代理类通过指针访问委托用户
}
virtual void vipMovoe() {
cout << "你不是vip,看不了" << endl;
}
virtual void ticketMovie() {
cout << "你没买票你看不了" << endl;
}
private:
VideoSite* pVideo;
};
class Proxyvip : public VideoSite {
public:
Proxyvip() {
pVideo = new FixBugVideoSite();
}
~Proxyvip() {
delete pVideo;
}
virtual void freeMovie() {
pVideo->freeMovie();//代理类通过指针访问委托用户
}
virtual void vipMovoe() {
pVideo->vipMovoe();
}
virtual void ticketMovie() {
cout << "你没买票你看不了" << endl;
}
private:
VideoSite* pVideo;
};
int main() {
unique_ptr<VideoSite> p1(new Proxyvip());
unique_ptr<VideoSite> p2(new Proxyfree());
p1->vipMovoe();
p2->vipMovoe();
return 0;
}
装饰器模式
主要是增加现有类的功能,另一个办法是新增加一个子类,这样子类太多了
使用一个装饰器类继承被装饰的基类,装饰器类中存放一个基类的指针,调用的还是被装饰者的方法,但是加上自己的装饰内容
class Car{}
class BMW:public Car{}
//装饰器1定速巡航
class carDercorator01 :public Car {
public:
carDercorator01(Car *p):pCar(p){}
void show() {
pCar->show();
cout << "已开启定速巡航"<<endl;
}
private:
//需要被装饰的对象
Car* pCar;
};
class carDercorator02 :public Car {
public:
carDercorator02(Car* p) :pCar(p) {}
void show() {
pCar->show();
cout << "已开启自动驾驶" << endl;
}
private:
Car* pCar;
};
int main() {
Car* p1 = new carDercorator01(new Bmw("asd"));
p1->show();
//两个装饰都装饰上
Car* p2 = new carDercorator02(p1);
p2->show();
return 0;
}
适配器模式
让不兼容的接口,可以一起工作
class VGA {
public:
virtual void play() = 0;
string getType() { return "VGA"; }
};
//VGA投影仪
class TV01 : public VGA {
public:
void play() {
cout << "通过VGA连接投影仪,play" << endl;
}
};
class HDMI {
public:
virtual void play() = 0;
string getType() { return "HDMI"; }
};
//HDMI投影仪
class TV02 : public HDMI {
public:
void play() {
cout << "通过HDMI连接投影仪,play" << endl;
}
};
class Computer {
public:
//只支持VGA接口的
void playVideo(VGA* pVGA) {
pVGA->play();
}
};
//适配器类,继承自原来的接口同时拥有新接口的指针。
class VGAToHDMIAdapter : public VGA {
public:
VGAToHDMIAdapter(HDMI* p):phdmi(p) { }
void play() {
phdmi->play();
}
private:
HDMI* phdmi;
};
int main() {
Computer comp;//只支持VGA,
//comp.playVideo(new TV01());
//使用HDMI的投影仪,投影VGA的电脑
comp.playVideo(new VGAToHDMIAdapter(new TV02()));
return 0;
}
适配器类,继承自原来的接口同时拥有新接口的指针。
观察者模式
主要关注对象 是一对多的关系,多个对象依赖于一个对象,当对象发生变化,其他对象收到通知
class Observer
{
public:
//处理消息的接口
virtual void handle(int msgid) = 0;
};
class Observer1 : public Observer
{
public:
void handle(int msgid) override
{
switch (msgid)
{
case 1:
cout << "Observer1 handle 1" << endl;
break;
case 2:
cout << "Observer1 handle 2" << endl;
break;
case 3:
cout << "Observer1 handle 3" << endl;
break;
default:
break;
}
}
};
class Observer2 : public Observer
{
public:
void handle(int msgid) override
{
switch (msgid)
{
case 1:
cout << "Observer2 handle 1" << endl;
break;
case 2:
cout << "Observer2 handle 2" << endl;
break;
case 3:
cout << "Observer2 handle 3" << endl;
break;
default:
break;
}
}
};
class Subject
{
public:
void addObserver(Observer* obser, int msgid)
{
_subMap[msgid].push_back(obser);
}
void dispatch(int msgid)
{
for (auto p : _subMap[msgid])
{
p->handle(msgid);
}
}
private:
//int:消息id list:对消息id感兴趣的观察者
unordered_map<int, list<Observer*>> _subMap;
};
int main()
{
Observer1 ob1;
Observer2 ob2;
Subject s1;
s1.addObserver(&ob1, 1);
s1.addObserver(&ob2, 1);
s1.dispatch(1);
return 0;
}