Observer
动机
- 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密, 将使软件不能很好地抵御变化。
- 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合
模式定义
定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
#include <iostream>
#include <vector>//或者Listclass Subject; // 稳定的class Observer // 稳定的
{
public:virtual ~Observer() {}virtual int getState() = 0;virtual void update(Subject *subject) = 0;// ...
};class ConcreteObserver : public Observer
{
public:ConcreteObserver(const int state) : observer_state(state) {}~ConcreteObserver() {}int getState(){return observer_state;}void update(Subject *subject);// ...private:int observer_state;// ...
};class Subject // 稳定的
{
public:virtual ~Subject() {}void attach(Observer *observer){observers.push_back(observer);}void detach(const int index){observers.erase(observers.begin() + index);}void notify(){for (unsigned int i = 0; i < observers.size(); i++){//自动更新observers.at(i)->update(this);}}virtual int getState() = 0;virtual void setState(const int s) = 0;// ...private:std::vector<Observer *> observers;// ...
};class ConcreteSubject : public Subject
{
public:~ConcreteSubject() {}int getState(){return subject_state;}void setState(const int s){subject_state = s;}// ...private:int subject_state;// ...
};void ConcreteObserver::update(Subject *subject)
{observer_state = subject->getState();std::cout << "Observer state updated." << std::endl;
}int main()
{ConcreteObserver observer1(1);ConcreteObserver observer2(2);std::cout << "Observer 1 state: " << observer1.getState() << std::endl;std::cout << "Observer 2 state: " << observer2.getState() << std::endl;Subject *subject = new ConcreteSubject();subject->attach(&observer1); // push_backsubject->attach(&observer2);subject->setState(10);subject->notify();std::cout << "Observer 1 state: " << observer1.getState() << std::endl;std::cout << "Observer 2 state: " << observer2.getState() << std::endl;delete subject;return 0;}
/*
Observer 1 state: 1
Observer 2 state: 2
Observer state updated.
Observer state updated.
Observer 1 state: 10
Observer 2 state: 10
*/
使用场景
- 当抽象有两个方面,一个依赖于另一个方面
- 当对一个对象的更改需要更改其他对象,而你不知道需要更改多少个对象时
- 当一个对象应该能够通知其他对象而不假设这些对象是谁时
总结
- 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。
- 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。
- 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
- Observer模式是基于事件的UI框架中非常常用的设计模式,也是 MVC模式的一个重要组成部分。