观察者模式(发布/订阅模式)
是一种行为模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察”该对象的其他对象
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使得它们能够自动更新自己。
#include <iostream>
#include <list>
#include <string>using namespace std;// 观察者(订阅者)的抽象类,里面包含一个Update方法
class IObserver
{
public:virtual ~IObserver(){};virtual void Update(const string &message_from_subject) = 0;
};// 主题/通知者(发布者)的抽象类,里面包含add、remove等方法
class ISubject
{
public:virtual ~ISubject(){};virtual void Attach(IObserver *observer) = 0;virtual void Detach(IObserver *onserver) = 0;virtual void Notify() = 0;
};// 发布者在状态发生变化时通知观察者
class Subject : public ISubject
{
public:virtual ~Subject(){cout << "Goodbye, I was the Subject. " << endl;}void Attach(IObserver *observer) override{list_observer_.push_back(observer);}void Detach(IObserver *observer) override{list_observer_.remove(observer);}void Notify() override{auto iterator = list_observer_.begin();cout << "There are " << list_observer_.size() << " observers in the list. " << endl;while (iterator != list_observer_.end()){(*iterator)->Update(message_);++iterator;}}// 状态改变,通知订阅者void CreateMessage(string message = "Empty"){this->message_ = message;this->Notify();}private:list<IObserver *> list_observer_;string message_;
};// 具体的观察者
class Observer : public IObserver
{
public:Observer(ISubject *subject) : subject_(subject) // 依赖抽象,而非依赖具体的subject对象{this->subject_->Attach(this); // 添加到监听列表cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";this->number_ = Observer::static_number_;}virtual ~Observer(){cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";}void Update(const string &message_from_subject) override{message_from_subject_ = message_from_subject;std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";}void RemoveMeFromTheList(){subject_->Detach(this);cout << "Observer \"" << number_ << "\" removed from the list.\n";}private:string message_from_subject_;ISubject *subject_;static int static_number_;int number_;
};int Observer::static_number_ = 0;// 客户端代码
void ClientCode()
{Subject *subject = new Subject;Observer *observer1 = new Observer(subject);Observer *observer2 = new Observer(subject);Observer *observer3 = new Observer(subject);Observer *observer4;Observer *observer5;subject->CreateMessage("Hello World! :D");observer3->RemoveMeFromTheList();subject->CreateMessage("The weather is hot today! :p");observer4 = new Observer(subject);observer2->RemoveMeFromTheList();observer5 = new Observer(subject);subject->CreateMessage("My new car is great! ;)");observer5->RemoveMeFromTheList();observer4->RemoveMeFromTheList();observer1->RemoveMeFromTheList();delete observer5;delete observer4;delete observer3;delete observer2;delete observer1;delete subject;
}int main()
{ClientCode();return 0;
}
输出:
Hi, I'm the Observer "1".
Hi, I'm the Observer "2".
Hi, I'm the Observer "3".
There are 3 observers in the list.
Observer "1": a new message is available --> Hello World! :D
Observer "2": a new message is available --> Hello World! :D
Observer "3": a new message is available --> Hello World! :D
Observer "3" removed from the list.
There are 2 observers in the list.
Observer "1": a new message is available --> The weather is hot today! :p
Observer "2": a new message is available --> The weather is hot today! :p
Hi, I'm the Observer "4".
Observer "2" removed from the list.
Hi, I'm the Observer "5".
There are 3 observers in the list.
Observer "1": a new message is available --> My new car is great! ;)
Observer "4": a new message is available --> My new car is great! ;)
Observer "5": a new message is available --> My new car is great! ;)
Observer "5" removed from the list.
Observer "4" removed from the list.
Observer "1" removed from the list.
Goodbye, I was the Observer "5".
Goodbye, I was the Observer "4".
Goodbye, I was the Observer "3".
Goodbye, I was the Observer "2".
Goodbye, I was the Observer "1".
Goodbye, I was the Subject.
- 观察者模式的特点
观察者模式所做的工作其实就是在解除耦合,让耦合的双方都依赖于抽象,,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化