观察者模式(Observer) 应用背景
日常微信使用中,常常订阅一些自己关注的公众号,当公众号文章更新时,相关订阅者会及时收到信息,这是生活中常见的一种方式,又例如你到店里购买化妆品时,长期喜欢的一款化妆品恰好售罄,你感到很遗憾,但店员通常建议你可以留一个联系方式,将来到货时第一时间通知你购买,免去了你隔山差五再次到店里询问的麻烦。软件设计中,使用观察者模式(Observer)表示这种情景。
观察者模式(Observer)定义了一种一对多的依赖关系,当一个对象的状态发生改变时,会通知所有依赖于它的对象,使它们能够自动更新自己。
观察者模式(Observer) UML表示
观察者模式(Observer) 代码示例
struct SubjectState
{
//to do whatever
std::string strState;
};
class Subject
{
public:
Subject(){}
virtual ~Subject(){}
virtual void Attach(Observer* pObj)
{
m_lstObserver.push_back(pObj);
}
virtual void Detach(Observer* pObj)
{
std::list<Observer*>::iterator itor;
itor = std::find(m_lstObserver.begin(), m_lstObserver.end(), pObj);
if(itor != m_lstObserver.end())
{
m_lstObserver.erase(itor);
}
}
virtual void Notify()
{
std::list<Observer*>::iterator itor;
for(itor=m_lstObserver.begin(); itor!=m_lstObserver.end(); ++itor)
{
(*itor)->Update();
}
}
virtual void SetState(SubjectState state) = 0;
virtual SubjectState GetState() = 0;
private:
std::list<Observer*> m_lstObserver;
};
class ConcreteSubject : public Subject
{
public:
ConcreteSubject()
{
m_subState.strState = "";
}
virtual ~ConcreteSubject(){}
void SetState(SubjectState state)
{
m_subState = state;
}
SubjectState GetState()
{
return m_subState;
}
private:
SubjectState m_subState;
};
class Observer
{
public:
Observer(){}
virtual ~Observer(){}
virtual void Update() = 0;
};
class ConcreteObserverA: public Observer
{
public:
ConcreteObserverA(Subject* sub):m_pSubject(sub){}
~ConcreteObserverA(){}
void Update()
{
//to do whatever
if(m_pSubject != NULL)
m_pSubject->GetState();
}
private:
Subject* m_pSubject;
};
class ConcreteObserverB: public Observer
{
public:
ConcreteObserverB(Subject* sub):m_pSubject(sub){}
~ConcreteObserverB(){}
void Update()
{
//to do whatever
if(m_pSubject != NULL)
m_pSubject->GetState();
}
private:
Subject* m_pSubject;
};
//usage example
Subject* pSubject = new ConcreteSubject();
Observer* pObserverA = new ConcreteObserverA(pSubject);
Observer* pObserverB = new ConcreteObserverB(pSubject);
pSubject->Attach(pObserverA);
pSubject->Attach(pObserverB);
pSubject->Notify();
pSubject->Detach(pObserverB);
pSubject->Notify();
delete pObserverA;
pObserverA = NULL;
delete pObserverB;
pObserverB = NULL;
delete pSubject;
pSubject = NULL;
实际使用中,当一个对象的改变需要同时改变其他对象的时候,并且该对象不知道具体有多少对象有待改变时,应该考虑使用观察者模式。观察者模式实现了解除耦合,让耦合的双方都依赖于抽象而非依赖于具体,从而使得各自的变化都不会影响另一边的变化。