OBSERVER(观察者) —— 对象行为型模式
概述:定义对象间的一种一对多的依赖关系,当目标对象的状态发生改变,所有依赖于它的对象都得到通知并被自动更新。
关键对象:目标(subject) 、观察者(observer)
交互方式:发布(public) - 订阅(subscribe)
适用场景:
当一个抽象模型有两个方面,其中一方面依赖于另一方面。需要将这两方面封装在独立的对象中以使它们可以各自独立的改变和复用;
当一个对象的改变需要同时改变其它对象,而该对象不知道具体有多少对象需要改变;
当一个对象必须通知其它对象,而它又不能假定其它对象是谁,这些对象是松耦合的。
结构图示:
优缺点:
- 目标和观察者之间的耦合是抽象的和最小的;
- 可以广播通信。目标发送的通知不需指定它的接受者,通知被自动广播给所有已向该目标对象登记的有关对象;
- 因为一个观察者并不知道其它观察者的存在,所以它可能对改变目标的最终影响一无所知。有时候在目标上看似无害的操作可能会引起一系列观察者以及依赖于这些观察者的那些对象的更新。
代码实现:
抽象观察者
file: IObserver.h
#ifndef _IOBSERVER_H_
#define _IOBSERVER_H_
class ISubject;
class IObserver {
public:
IObserver() {}
virtual ~IObserver(){}
virtual void Update(ISubject *theChangedSubject) = 0;
};
#endif
抽象目标
file: ISubject.h
#ifndef _ISUBJECT_H_
#define _ISUBJECT_H_
#include "IObserver.h"
class ISubject {
public:
ISubject(){}
virtual ~ISubject(){}
virtual void Attach(IObserver *) = 0;
virtual void Detach(IObserver *) = 0;
virtual void Notify() = 0;
};
#endif
具体观察者1
file: AConcreteObserver.h
#ifndef _ACONCRETE_OBSERVER_H_
#define _ACONCRETE_OBSERVER_H_
#include "IObserver.h"
#include "AConcreteSubject.h"
class AConcreteObserver: public IObserver {
public:
AConcreteObserver(AConcreteSubject *s);
virtual ~AConcreteObserver();
virtual void Update(ISubject* theChangedSubject);
private:
int m_observerState;
AConcreteSubject* m_subject;
};
#endif
file: AConcreteObserver.cpp
#include "AConcreteObserver.h"
#include <iostream>
AConcreteObserver::AConcreteObserver(AConcreteSubject* s) {
m_subject = s;
m_subject->Attach(this);
}
AConcreteObserver::~AConcreteObserver() {
m_subject->Detach(this);
std::cout << "~AConcreteObserver" << std::endl;
}
void AConcreteObserver::Update(ISubject* theChangedSubject) {
if (theChangedSubject == m_subject) {
m_observerState = m_subject->GetState();
std::cout << "AConcreteObserver got the update: m_observerState = " << m_observerState << std::endl;
}
}
具体观察者2
file: AnotherConcreteObserver.h
#ifndef _ANOTHERCONCRETE_OBSERVER_H_
#define _ANOTHERCONCRETE_OBSERVER_H_
#include "IObserver.h"
#include "AConcreteSubject.h"
class AnotherConcreteObserver: public IObserver {
public:
AnotherConcreteObserver(AConcreteSubject *s);
virtual ~AnotherConcreteObserver();
virtual void Update(ISubject* theChangedSubject);
private:
int m_observerState;
AConcreteSubject* m_subject;
};
#endif
file: AnotherConcreteObserver.cpp
#include "AnotherConcreteObserver.h"
#include <iostream>
AnotherConcreteObserver::AnotherConcreteObserver(AConcreteSubject* s) {
m_subject = s;
m_subject->Attach(this);
}
AnotherConcreteObserver::~AnotherConcreteObserver() {
m_subject->Detach(this);
std::cout << "~AnotherConcreteObserver" << std::endl;
}
void AnotherConcreteObserver::Update(ISubject* theChangedSubject) {
if (theChangedSubject == m_subject) {
m_observerState = m_subject->GetState();
std::cout << "AnotherConcreteObserver got the update: m_observerState = " << m_observerState << std::endl;
}
}
具体目标
file: AConcreteSubject.h
#ifndef _ACONCRETE_SUBJECT_H_
#define _ACONCRETE_SUBJECT_H_
#include <iostream>
#include <list>
#include "ISubject.h"
class AConcreteSubject: public ISubject {
public:
AConcreteSubject();
virtual ~AConcreteSubject();
void Attach(IObserver *pObserver);
void Detach(IObserver *pObserver);
void Notify();
void SetState(int state);
int GetState();
private:
std::list<IObserver *> m_ObserverList;
int m_subjectState;
};
#endif
file: AConcreteSubject.cpp
#include "AConcreteSubject.h"
AConcreteSubject::AConcreteSubject() {
}
AConcreteSubject::~AConcreteSubject() {
m_ObserverList.clear();
}
void AConcreteSubject::Attach(IObserver *pObserver) {
m_ObserverList.push_back(pObserver);
}
void AConcreteSubject::Detach(IObserver *pObserver) {
m_ObserverList.remove(pObserver);
}
void AConcreteSubject::Notify() {
std::list<IObserver *>::iterator iter = m_ObserverList.begin();
while(iter != m_ObserverList.end()) {
(*iter)->Update(this);
++iter;
}
}
void AConcreteSubject::SetState(int state) {
m_subjectState = state;
}
int AConcreteSubject::GetState() {
return m_subjectState;
}
file: main.cpp
#include <iostream>
#include "ISubject.h"
#include "IObserver.h"
#include "AConcreteSubject.h"
#include "AConcreteObserver.h"
#include "AnotherConcreteObserver.h"
using namespace std;
int main(int argc, char *argv[]) {
//目标实例化
AConcreteSubject *pSubject = new AConcreteSubject();
//创建观察者
IObserver *pAConcreteObserver = new AConcreteObserver(pSubject);
IObserver *pAnotherConcreteObserver = new AnotherConcreteObserver(pSubject);
pSubject->SetState(0);
pSubject->Notify();
cout << "-----------------" << endl;
pSubject->SetState(1);
pSubject->Notify();
cout << "-----------------" << endl;
delete pAConcreteObserver;
pSubject->SetState(2);
pSubject->Notify();
cout << "-----------------" << endl;
delete pAnotherConcreteObserver;
pSubject->SetState(3);
pSubject->Notify();
delete pSubject;
cout << "+++ End +++ " << endl;
return 0;
}
输出
AConcreteObserver got the update: m_observerState = 0
AnotherConcreteObserver got the update: m_observerState = 0
-----------------
AConcreteObserver got the update: m_observerState = 1
AnotherConcreteObserver got the update: m_observerState = 1
-----------------
~AConcreteObserver
AnotherConcreteObserver got the update: m_observerState = 2
-----------------
~AnotherConcreteObserver
+++ End +++