Observer/Event观察者模式(C++)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/i_chaoren/article/details/80561204

动机: 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”--一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。
使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

松耦合可以体现在下面几种情况:
1)一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
2)一个对象的改变将导致其他一个或多个对象也发生改变,而不需要知道具体有多少对象、这些对象是谁

GOF定义:定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象(Observer)都得到通知并自动更新。


举例: 对同一组数据进行统计分析时候, 我们希望能够提供多种形式的表示 (例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据, 我们当然需要当数据改变的时候, 所有的统计的显示都能够同时改变。 Observer 模式就是解决了这一个问题。

总结:解决一对多的问题,同时保证观察者与被观察者之间为松耦合。

下面代码展示了Observer模式的整个框架和流程。

#include <iostream>
#include <list>
using namespace std;

class Observer;
//抽象被观察者
class Subject {
public:
	virtual void Attach(Observer *) = 0;
	virtual void Detach(Observer *) = 0;
	virtual void Notify() = 0;
	virtual int GetState() { return state_; }
	void SetState(int state) { state_ = state; }
protected:
	std::list<Observer *> observer_list_;
	int state_;
};
//抽象观察者
class Observer {
public:
	Observer(Subject *sub):p_subject_(sub){}
	virtual void Update() = 0;
protected:
	Subject* p_subject_;
};

//具体观察者1
class Observer1 : public Observer {
public:
	Observer1(Subject *p_subject) : Observer(p_subject) {}
	void Update() override {
		cout << "Observer1 get the update:" << p_subject_->GetState() << endl;
	}
};

//具体观察者2
class Observer2 : public Observer
{
public:
	Observer2(Subject *p_subject) : Observer(p_subject) {}
	void Update() override {
		cout << "Observer2 get the update:" << p_subject_->GetState() << endl;
	}
};

//具体被观察者
class ConcreteSubject : public Subject
{
public:
	void Attach(Observer *pObserver) override {
		observer_list_.push_back(pObserver); 
	}
	void Detach(Observer *pObserver) override { 
		observer_list_.remove(pObserver); 
	}
	void Notify() override ;
};

//核心操作:循环通知所有观察者
void ConcreteSubject::Notify() {
	auto it = observer_list_.begin();
	while (it != observer_list_.end()) {
		(*it++)->Update();
	}
}

int main()
{
	// 创建被观察者
	Subject *p_subject = new ConcreteSubject();

	// 创建观察者
	Observer *p_observer1 = new Observer1(p_subject);
	Observer *p_observer2 = new Observer2(p_subject);

	// 改变状态
	p_subject->SetState(2);

	// 注册观察者
	p_subject->Attach(p_observer1);
	p_subject->Attach(p_observer2);
	p_subject->Notify();

	// 注销观察值
	p_subject->Detach(p_observer1);

	p_subject->SetState(3);
	p_subject->Notify();

	delete p_observer1;
	delete p_observer2;
	delete p_subject;
}

猜你喜欢

转载自blog.csdn.net/i_chaoren/article/details/80561204
今日推荐