Observer
动机(Motivation)
- 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对
象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。 - 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。
模式定义
定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
——《 设计模式》 GoF
要点总结
- 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。
- 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。
- 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
- Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分。
代码结构
.
├── build.sh
├── clearBuild.sh
├── CMakeLists.txt
├── src
│ ├── examStu.cpp
│ ├── include
│ │ └── examStu.h
│ └── main.cpp
源码例子1 (定时器)
examStu.h
#ifndef _EXANSTU__
#define _EXANSTU__
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
//Observer
class TimerObserver
{
public:
TimerObserver()=default;
virtual ~TimerObserver(){};
virtual void OnTime(int value) = 0;
private:
};
//object
class Timer
{
public:
Timer()=default;
virtual ~Timer(){};
virtual void Notify() = 0;
virtual void AddObserver(TimerObserver*) = 0;
virtual void Detach(TimerObserver* )=0;
private:
};
class ShopingTimerObserver:public TimerObserver
{
public:
ShopingTimerObserver()=default;
ShopingTimerObserver(Timer* pTimer):m_pTimer(pTimer){}
~ShopingTimerObserver(){};
void OnTime(int value)
{
cout << "update Shoping state:" << value <<endl;
}
private:
Timer * m_pTimer;
};
class CookkingTimerObserver:public TimerObserver
{
public:
CookkingTimerObserver()=default;
CookkingTimerObserver(Timer* pTimer):m_pTimer(pTimer){}
~CookkingTimerObserver(){};
void OnTime(int value) override
{
cout << "update Cookking state:" << value <<endl;
}
private:
Timer * m_pTimer;
};
class ConcreteTimer : public Timer
{
public:
ConcreteTimer():m_State(0){}
~ConcreteTimer(){};
void AddObserver(TimerObserver* pTimerObserver)
{
m_pTimerObserverList.push_back(pTimerObserver);
}
void Detach(TimerObserver* pTimerObserver)
{
m_pTimerObserverList.remove(pTimerObserver);
}
void Notify()
{
std::list<TimerObserver *>::iterator it = m_pTimerObserverList.begin();
while (it != m_pTimerObserverList.end())
{
(*it)->OnTime(m_State);
++it;
}
}
void SetState(int state)
{
m_State = state;
}
private:
std::list<TimerObserver *> m_pTimerObserverList;
int m_State;
};
#endif
main.cpp
#include <iostream>
#include <string>
#include <memory>
#include "examStu.h"
using namespace std;
int main()
{
ConcreteTimer* pConcreteTimer = new ConcreteTimer();
TimerObserver* pShopingTimerObserver = new ShopingTimerObserver(pConcreteTimer);
TimerObserver* pCookkingTimerObserver = new CookkingTimerObserver(pConcreteTimer);
pConcreteTimer->AddObserver(pShopingTimerObserver);
pConcreteTimer->AddObserver(pCookkingTimerObserver);
pConcreteTimer->SetState(2);
pConcreteTimer->Notify();
// Unregister the observer
pConcreteTimer->Detach(pShopingTimerObserver);
pConcreteTimer->SetState(3);
pConcreteTimer->Notify();
delete pConcreteTimer;
delete pShopingTimerObserver;
delete pCookkingTimerObserver;
return 0;
}
源码例子2
examStu.h
#ifndef _EXANSTU__
#define _EXANSTU__
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
class Observer
{
public:
virtual void Update(int) = 0;
};
class Subject //timer
{
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;
};
class ConcreteObserver1 : public Observer
{
public:
ConcreteObserver1(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver1 get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
class ConcreteObserver2 : public Observer
{
public:
ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver2 get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
class ConcreteSubject : public Subject
{
public:
void Attach(Observer *pObserver)
{
m_ObserverList.push_back(pObserver);
}
void Detach(Observer *pObserver)
{
m_ObserverList.remove(pObserver);
}
void Notify()
{
std::list<Observer *>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end())
{
(*it)->Update(m_iState);
++it;
}
}
void SetState(int state)
{
m_iState = state;
}
private:
std::list<Observer *> m_ObserverList;
int m_iState;
};
#endif
main.cpp
#include <iostream>
#include <string>
#include <memory>
#include "examStu.h"
using namespace std;
int main(int argc, char *argv[])
{
// Create Subject
ConcreteSubject *pSubject = new ConcreteSubject();
// Create Observer
Observer *pObserver1 = new ConcreteObserver1(pSubject);
Observer *pObserver2 = new ConcreteObserver2(pSubject);
// Change the state
pSubject->SetState(2);
// Register the observer
pSubject->Attach(pObserver1);
pSubject->Attach(pObserver2);
pSubject->Notify();
// Unregister the observer
pSubject->Detach(pObserver1);
pSubject->SetState(3);
pSubject->Notify();
delete pObserver1;
delete pObserver2;
delete pSubject;
return 0;
}