设计模式

发布于:2024-12-21 ⋅ 阅读:(18) ⋅ 点赞:(0)

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