C++(9)——设计模式 观察者模式

设计模式 观察者模式

定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖的对象皆得到通知并被自动更新(发布-订阅模式)。

使用shared_ptr:

#include <iostream>
#include <list>
#include <memory>

/* 优化,使用智能指针shared_ptr代替* */
using namespace std;

class Observer {
public:
    virtual ~Observer() {
        cout << "~Observer()" << endl;
    }
    virtual void Update(int data) = 0;
};

class Subject {
public:
    virtual ~Subject() {
        cout << "~Subject()" << endl;
    }
    virtual void Attach(shared_ptr<Observer> pOb) = 0;
    virtual void Detach(shared_ptr<Observer> pOb) = 0;
    virtual void Notify() = 0;
};
// 具体观察者1
class ConcreteObserver_1 : public Observer {
public:
    ~ConcreteObserver_1() {
        cout << "~ConcreteObserver_1()" << endl;
    }
    ConcreteObserver_1(shared_ptr<Subject> pSubject) : m_pSubject(pSubject) {}
    void Update(int data) {
        cout << "ConcreteObserver_1 get data: " << data << endl;
    }
private:
    weak_ptr<Subject> m_pSubject;
    // shared_ptr<Subject> m_pSubject;
};
// 具体观察者2
class ConcreteObserver_2 : public Observer {
public:
    ~ConcreteObserver_2() {
        cout << "~ConcreteObserver_2()" << endl;
    }
    ConcreteObserver_2(shared_ptr<Subject> pSubject) : m_pSubject(pSubject) {}
    void Update(int data) {
        cout << "ConcreteObserver_2 get data: " << data << endl;
    }
private:
    weak_ptr<Subject> m_pSubject;
    // shared_ptr<Subject> m_pSubject;
};
// 具体 被观察目标:
class ConctreteSubject : public Subject {
public:
    void Attach(shared_ptr<Observer> pOb) override {
        m_ObVec.push_back(pOb);
    };
    void Detach(shared_ptr<Observer> pOb) override {
        m_ObVec.remove(pOb);
    }; //override 直接明了的告诉编译器该函数用于重载父类的某个虚函数
    void Notify() override {
        for(auto& ob : m_ObVec) {
            ob->Update(m_iStats);
        }
    };
    void SetStats(int stats) {
        m_iStats = stats;
    };
private:
    list<shared_ptr<Observer>> m_ObVec;
    int m_iStats;
};

int main() {
    auto pSubject = make_shared<ConctreteSubject>();

    auto pOserver_1 = make_shared<ConcreteObserver_1>(pSubject);
    auto pOserver_2 = make_shared<ConcreteObserver_2>(pSubject);
    //可以使用 pSubject.use_count() 查看shared_ptr计数
    cout << pOserver_1.use_count() << endl;
    cout << pOserver_2.use_count() << endl;
    cout << pSubject.use_count() << endl;

    pSubject->SetStats(1);
    pSubject->Attach(pOserver_1);
    pSubject->Attach(pOserver_2);
    pSubject->Notify();

    pSubject->SetStats(2);
    pSubject->Notify();

    cout << pOserver_1.use_count() << endl;
    cout << pOserver_2.use_count() << endl;
    cout << pSubject.use_count() << endl;

    // pSubject->Detach(pOserver_1);
    // pSubject->Detach(pOserver_2);

    cout << pOserver_1.use_count() << endl;
    cout << pOserver_2.use_count() << endl;
    cout << pSubject.use_count() << endl;
    return 0;
}
  • 上述代码中采用shared_ptr,pSubject和pOserver_1, pOserver_2循环计数,导致return 0是shared_ptr计数器不能减为0,无法析构。需要手动// pSubject->Detach(pOserver_2);,减掉shared_ptr的引用计数,才能顺利析构。
1
1
3
ConcreteObserver_1 get data: 1
ConcreteObserver_2 get data: 1
ConcreteObserver_1 get data: 2
ConcreteObserver_2 get data: 2
2
2
3
2
2
3
  • 可将shared_ptr m_pSubject;修改为weak_ptr m_pSubject;
1
1
1
ConcreteObserver_1 get data: 1
ConcreteObserver_2 get data: 1
ConcreteObserver_1 get data: 2
ConcreteObserver_2 get data: 2
2
2
1
2
2
1
~ConctreteSubject()
~ConcreteObserver_1()
~Observer()
~ConcreteObserver_2()
~Observer()
~Subject()

使用unique_ptr

  • unique_ptr是一个删除了拷贝构造函数、保留了移动构造函数的指针封装类型;
  • 与shared_ptr不同,某个时刻只能有一个unique_ptr指向一个给定对象;
  • 使用std::move进行拷贝
#include <iostream>
#include <list>
#include <memory>
using namespace std;

class Observer {
public:
    virtual ~Observer() {
        cout << "~Observer()" << endl;
    }
    virtual void Update(int data) = 0;
};

class Subject {
public:
    virtual ~Subject() {
        cout << "~Subject()" << endl;
    }
    virtual void Attach(unique_ptr<Observer> pOb) = 0;
    virtual void Detach(unique_ptr<Observer> pOb) = 0;
    virtual void Notify() = 0;
};
// 具体观察者1
class ConcreteObserver_1 : public Observer {
public:
    ~ConcreteObserver_1() {
        cout << "~ConcreteObserver_1()" << endl;
    }
    void Update(int data) {
        cout << "ConcreteObserver_1 get data: " << data << endl;
    }
};
// 具体观察者2
class ConcreteObserver_2 : public Observer {
public:
    ~ConcreteObserver_2() {
        cout << "~ConcreteObserver_2()" << endl;
    }
    void Update(int data) {
        cout << "ConcreteObserver_2 get data: " << data << endl;
    }
};
// 具体 被观察目标:
class ConctreteSubject : public Subject {
public:
    ~ConctreteSubject() {
        cout << "~ConctreteSubject()" << endl;
    }
    void Attach(unique_ptr<Observer> pOb) override;
    void Detach(unique_ptr<Observer> pOb) override; //override 直接明了的告诉编译器该函数用于重载父类的某个虚函数
    void Notify() override;

    void SetStats(int stats) {
        m_iStats = stats;
    };
private:
    list<unique_ptr<Observer>> m_ObVec;
    int m_iStats;
};

void ConctreteSubject::Attach(unique_ptr<Observer> ob) {
    m_ObVec.push_back(std::move(ob));
}

void ConctreteSubject::Detach(unique_ptr<Observer> ob) {
    m_ObVec.remove(ob);
}

void ConctreteSubject::Notify() {
    for(auto& ob : m_ObVec) {
        ob->Update(m_iStats);
    }
}

int main() {
    auto pSubject = make_unique<ConctreteSubject>();

    auto pOserver_1 = make_unique<ConcreteObserver_1>();
    auto pOserver_2 = make_unique<ConcreteObserver_2>();

    pSubject->SetStats(1);
    pSubject->Attach(std::move(pOserver_1));
    pSubject->Attach(std::move(pOserver_2));
    pSubject->Notify();

    pSubject->SetStats(2);
    pSubject->Notify();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值