设计模式 观察者模式
定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖的对象皆得到通知并被自动更新(发布-订阅模式)。
使用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();
}