版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxh2075/article/details/54290211
#ifndef __OBSERVER_H__
#define __OBSERVER_H__
#include <string>
#include <list>
//【说明】
// 观察者模式有时又被称为发布(Publish)-订阅(Subscribe)模式, 此种模式通常被用来实现事件处理系统。
//【定义】
// 观察者模式(Observer):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
//【角色】
// 1) 抽象主题(Subject)角色(接口):主题角色将所有观察者对象的引用保存在一个集合中,抽象主题提供了增加和删除观察者对象的接口。
// 2) 抽象观察者(Observer)角色(接口):为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。
// 3) 具体主题(ConcreteSubject)角色(1个):存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。
// 4) 具体观察者(ConcretedObserver)角色(多个):存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致。
//【意义】
// 当一个对象状态发生改变后,会影响到其他几个对象的改变,这时候可以用观察者模式。
// 观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
// 如此就可以对不同的观察者接收到同样的通知时做出不同的决策,如果需要对主题扩展,还需要观察者依赖于抽象主题。
//【示例】
class Subject;
//观察者接口
class iObserver
{
public:
iObserver(){ }
virtual ~iObserver(){ }
public:
virtual void Update(Subject * sub, void * arg) = 0; //定义观察者更新接口
};
//主题抽象类
class Subject
{
public:
typedef std::list<iObserver*> OBList;
public:
Subject();
virtual ~Subject();
public:
void Notify(); //通知接口
void Add(iObserver* ob);
void Remove(iObserver* ob);
virtual void SetMessage(std::string message) = 0;
std::string GetMessage();
private:
OBList m_list;
protected:
std::string m_message;
};
//学生是一种观察者
class Student : public iObserver
{
public:
virtual void Update(Subject * sub, void * arg);
};
//老师是另一种观察者
class Teacher : public iObserver
{
public:
virtual void Update(Subject * sub, void * arg);
};
//天气是一种主题
class Weather : public Subject
{
public:
virtual void SetMessage(std::string message);
};
//学校通知也是一种主题
class School : public Subject
{
public:
virtual void SetMessage(std::string message);
};
void TestObserver();
#endif
#include "Observer.h"
Subject::Subject()
{
}
Subject::~Subject()
{
for(OBList::iterator iter = m_list.begin(); iter != m_list.end(); iter++)
{
if (*iter != NULL)
{
delete *iter;
*iter = NULL;
}
}
}
void Subject::Notify()
{
for(OBList::iterator iter = m_list.begin(); iter != m_list.end(); iter++)
{
iObserver * ob = * iter;
ob->Update(this, NULL);
}
}
void Subject::Add(iObserver* ob)
{
m_list.push_back(ob);
}
void Subject::Remove(iObserver* ob)
{
m_list.remove(ob);
}
std::string Subject::GetMessage()
{
return m_message;
}
void Student::Update(Subject * sub, void * arg)
{
printf("student : subject is %s \n", sub->GetMessage().c_str());
}
void Teacher::Update(Subject * sub, void * arg)
{
printf("teacher : subject is %s \n", sub->GetMessage().c_str());
}
void Weather::SetMessage(std::string message)
{
m_message = "Weather : " + message;
}
void School::SetMessage(std::string message)
{
m_message = "School : " + message;
}
void TestObserver()
{
Subject * sub1 = new Weather();
sub1->Add(new Student());
sub1->Add(new Teacher());
sub1->SetMessage("rain");
sub1->Notify();
delete sub1;
Subject * sub2 = new School();
sub2->Add(new Student());
sub2->Add(new Teacher());
sub2->SetMessage("holiday");
sub2->Notify();
delete sub2;
return;
}