设计模式之观察者模式

观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在主题对象的状态发生变化时,会通知所有的观察者。

观察者模式角色如下:

抽象主题(Subject)角色:抽象主题角色提供维护一个观察者对象集合的操作方法,对集合的增加、删除等。
具体主题(ConcreteSubject)角色:将有关状态存入具体的观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发通知。具体主题角色负责实现抽象主题中的方法。
抽象观察者(Observer)角色:为具体观察者提供一个更新接口。
具体观察者(ConcreteObserver)角色:存储与主题相关的自洽状态,实现抽象观察者提供的更新接口。

 

 Case:

在教室里老师还没有来,同学都在干着各的事情,小张正在打游戏,小李正在抄作业.....,  现在同学们要求班长当卧底,监视老师,当老师来了通知大家一声。然后打游戏的马上停止,抄作业的也停止。

这里班长相当于是一个通知者, 小张、小李,以及其他同学显然是监听者,他们监听了班长那的消息,一旦老师来了马上采取相关的行动。

 


首先,先把通知者的行为抽象为一个接口:(subject)

class INotifier
{
public:
    virtual void registerListenner(ITeacherListenner *l) =0 ;
    virtual void removeListenner(ITeacherListenner *l) =0 ; 
    virtual void notify() =0 ;    
};

第二,然后班长作为一个具体的通知者:(ConcreteSubject)
class MonitorNotifier:public INotifier
{
public:
    void registerListenner(ITeacherListenner *l)
    {
        listenners.push_back(l);
    }

    void removeListenner(ITeacherListenner *l)
    {
        list<ITeacherListenner*>::iterator it;
        for(it=listenners.begin();it!=listenners.end();it++)
        {
            if(*it == l)
            {
                listenners.remove(l);
                break;
            }
        }
    }

    void notify()
    {
        list<ITeacherListenner*>::iterator it;
        for(it=listenners.begin();it!=listenners.end();it++)
        {
            (*it)->onTecherComming(mValue;); 
     }
    } 

    void setValue(int value)
    {
     mValue = value;
     notify();
    }
private: 
  list<ITeacherListenner*> listenners; 
  int mValue;
};


第三, 定义一个监听者的接口,想要监听老师来了这个消息的同学必须要实现这个接口:

class ITeacherListenner
{
public:
    virtual void onTecherComming(int value) = 0; 
};


第四,ZhangSan 和 LiSi 监听了老师来了这个接口:
class ZhangSan:public ITeacherListenner
{
public:
    void onTecherComming(int value)
    {
        stopCopyWork(value);
    }
    
    void stopCopyWork(int value)
    {
        cout<<"zhangsan stopCopyWork + "<<value<<endl;
    }
};

class LiSi:public ITeacherListenner
{
public:
    void onTecherComming(int value)
    {
        stopPlayGame(value);
    }
    void stopPlayGame(int value)
    {
        cout<<"lisi stopPlayGame + "<<value<<endl;
    }
};

int main()
{
   cout << "Hello World1-------------"<<endl;
   MonitorNotifier monitor;
   ZhangSan zs;
   LiSi ls;
   monitor.registerListenner(&zs);
   monitor.registerListenner(&ls);
   monitor.setValue(1);
    
   cout << "Hello World2-------------"<<endl;
   monitor.removeListenner(&ls);
   monitor.setValue(2);
    
   return 0;
}

运行结果如下:
Hello World1-------------
zhangsan stopCopyWork + 1
lisi stopPlayGame + 1
Hello World2-------------
zhangsan stopCopyWork + 2

 

 

示例2

#include <iostream>
#include <vector>
#include <string>
using namespace std;

///抽象一个Subject主题
///观察者
class Observer {
public:
	virtual void update(string m_Temp, string m_Humi) = 0;
protected:
	Observer() {}
};
class Subject {
public:
	virtual void registerObserver(Observer* pObj)=0;
	virtual void removeObserver(Observer* pObj)=0;
	virtual void noitfyObserver()=0;
protected:
	Subject(){}
};

class WeatherData :public Subject {
public:
	WeatherData(string Temp, string Humi) : m_Temp(Temp), m_Humi(Humi) {
	}
	void registerObserver(Observer* pObj) {
		m_observers.push_back(pObj);
	}
	void removeObserver(Observer* pObj) {
		auto iter = find(m_observers.begin(), m_observers.end(), pObj);
		if (iter != m_observers.end()) {
			m_observers.erase(iter);
		}
	}
	void noitfyObserver() {
		//逐个遍历调用Observer的update方法
		for (vector<Observer*>::iterator iter = m_observers.begin();iter != m_observers.end();iter++) {
			(*iter)->update(m_Temp, m_Humi);
			
		}
	}

	void setData(string Temp, string Humi) {
		m_Temp = Temp;
		m_Humi = Humi;
		noitfyObserver();
	}
private:
	vector<Observer*> m_observers;
	string m_Temp;//温度
	string m_Humi;//湿度
};




//CocreteObserver
class PCDisplay:public Observer {
public:
	void update(string m_Temp, string m_Humi) {
		cout << "我是PC端的显示GUI,当前的温度为" << m_Temp << "湿度为" << m_Humi << endl;
	}

	PCDisplay(WeatherData* pWeatherData) {
		m_pWeatherData = pWeatherData;
		m_pWeatherData->registerObserver(this);
	}
private:
	WeatherData* m_pWeatherData;
};



class MobileDisplay :public Observer {
public:
	void update(string m_Temp, string m_Humi) {
		cout << "我是Mobile端的显示GUI,当前的温度为" << m_Temp << "湿度为" << m_Humi << endl;
	}

	MobileDisplay(WeatherData* pWeatherData) {
		m_pWeatherData = pWeatherData;
		m_pWeatherData->registerObserver(this);
	}
private:
	WeatherData* m_pWeatherData;
};


int main(void) {
	WeatherData* pWD = new WeatherData("22C", "65%");
	PCDisplay* pPCDisplay = new PCDisplay(pWD);
	MobileDisplay* pMobile = new MobileDisplay(pWD);

	pWD->setData("38C", "55%");
	pWD->removeObserver(pMobile);
	pWD->setData("31", "44%");
	
	system("pause");
	return 0;
}

示例3

#include <iostream>
#include <list>
#include <string>
using namespace std;

class Observer { // 抽象观察者,为所有具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫更新接口
public:
    virtual void Update() = 0;
};

class Subject { // 主题或抽象通知者,一般用一个抽象类或者接口实现
private:
    list<Observer* > observers;
public:
    void Attach(Observer* observer) { observers.push_back(observer); } // 增加观察者
    void Detach(Observer* observer) { observers.remove(observer); } // 移除观察者
    void Notify() { // 通知
        for (auto observer = observers.begin(); observer != observers.end(); observer++) {
            (*observer)->Update();
        }
    }
};

class ConcreteSubject : public Subject { // 具体主题或具体通知者,将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发送通知
private:
    string subjectState;
public:
    string GetState() { return subjectState; }
    void SetState(string state) { subjectState = state; }
};

class ConcreteObserver : public Observer { // 具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态相协调
private:
    string name;
    ConcreteSubject* subject;
    string observerState;
public:
    ConcreteObserver(ConcreteSubject* s, string n) {
        subject = s;
        name = n;
    }
    void Update() {
        observerState = subject->GetState();
        cout << "observer: " << name << ", its new state is: " << observerState << endl;
    }
    string GetState() { return observerState; }
    void SetState(string state) { observerState = state; }
};

int main() {
    ConcreteSubject* s = new ConcreteSubject();
    s->SetState("ABC");
    ConcreteObserver* ox = new ConcreteObserver(s, "X");
    ConcreteObserver* oy = new ConcreteObserver(s, "Y");
    ConcreteObserver* oz = new ConcreteObserver(s, "Z");
    s->Attach(ox);
    s->Attach(oy);
    s->Attach(oz);
    s->Notify();
    // observer: X, its new state is: ABC
    // observer: Y, its new state is: ABC
    // observer: Z, its new state is: ABC
    s->SetState("XYZ");
    s->Notify();
    // observer: X, its new state is: XYZ
    // observer: Y, its new state is: XYZ
    // observer: Z, its new state is: XYZ
    delete ox;
    delete oy;
    delete oz;
    delete s;
    return 0;
}

         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值