设计模式—行为型-Observer(观察者)
1. 意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
2. 结构图
3. 简述
Subject目标是一个个数据模块。Observer观察者是观察这些数据模块并向用户做出展示的对象。MVC模式可以看成是改模式的一个特例。Subject相当于MVC中的Model,Observer相当于MVC中的View。
结构图中Subject存储了对它感兴趣的Observer的列表,在目标数据改变时自行调用或由客户Client程序调用Notify()从而通知所有Observer,各个Observer通过Update()更新自身的显示。但是有两种情况:一是一个Subject对应多个Observer;二是一个Observer对应多个Subject。所以何时调用Subject的Notify以及何时调用Observer的Update就有了很多考量。出现了一种衍生版的观察者模式,加入ChangeManager来管理通知和更新的问题,并维持一个Subject-Object映射表。这个ChangeManager是用到Mediator中介者模式。
4. 实例代码
// 中介者模式,在subject和observer间进行协调
class ChangeManager
{
static ChangeManager * _instance;
multimap<Subject, Observer>;
ChangeManager(const ChangeManager &);
ChangeManager& operator=(const ChangeManager &);
public:
static ChangeManager* GetInstance()
{
If(!_instance)
_ instance = new ChangeManager;
return _ instance;
}
void Register(Subject, Observer);
void Unregister(Subject, Observer);
void Notify(Subject*)
}
// 目标。也是MVC中的Model
class Subject
{
virtual ~ Subject ();
virtual void Attach(Observer*)
{
ChangeManager::GetInstance()->Register(this, Observer);
}
virtual void Detach(Observer*)
{
ChangeManager::GetInstance()->Unregister(this, Observer);
}
virtual void Notify()
{
ChangeManager::GetInstance()->Notify(this);
}
};
// 观察者。也是MVC中的View
class Observer
{
virtual ~ Observer();
void Update(Subject*) = 0;
};
class ConcreteSubject : public Subject
{
ConcreteSubject ();
bool GetBoolValue();
int GetIntValue();
float GetFloatValue();
};
class ConcreteObserver
{
Observer();
void Update(Subject*);
};
// 中介者模式,在subject和observer间进行协调
class ChangeManager
{
static ChangeManager * _instance;
multimap<Subject, Observer>;
ChangeManager(const ChangeManager &);
ChangeManager& operator=(const ChangeManager &);
public:
static ChangeManager* GetInstance()
{
If(!_instance)
_ instance = new ChangeManager;
return _ instance;
}
void Register(Subject, Observer);
void Unregister(Subject, Observer);
void Notify(Subject*)
}
// 目标。也是MVC中的Model
class Subject
{
virtual ~ Subject ();
virtual void Attach(Observer*)
{
ChangeManager::GetInstance()->Register(this, Observer);
}
virtual void Detach(Observer*)
{
ChangeManager::GetInstance()->Unregister(this, Observer);
}
virtual void Notify()
{
ChangeManager::GetInstance()->Notify(this);
}
};
// 观察者。也是MVC中的View
class Observer
{
virtual ~ Observer();
void Update(Subject*) = 0;
};
class ConcreteSubject : public Subject
{
ConcreteSubject ();
bool GetBoolValue();
int GetIntValue();
float GetFloatValue();
};
class ConcreteObserver
{
Observer();
void Update(Subject*);
};