Observer

#include <iostream>
#include <string>
#include <list>
using namespace std;
 
enum E_STATE {
	OFF,
	ON
};
 
/*
 * observer: ボタン、LED
 * subject: コントローラ
 */
 
// prototype
class Observer;
 
// 通知する人
class Subject {
public:
	void AddObserver(Observer *observer);
	void DelObserver(Observer *observer);
	virtual void NotifyObserver();
protected:
	list<Observer*> m_observers;
};
 
class Controller : public Subject {
public:
	Controller() {
		m_state = OFF;
	}
	virtual void NotifyObserver();
	E_STATE GetState() {
		return m_state;
	}
	void SetState(E_STATE state) {
		m_state = state;
	}
private:
	E_STATE m_state;
};
 
 
/// 監視する人
class Observer {
public:
	virtual void Update(Subject *subject) = 0;
};
 
class ButtonObserver : public Observer {
public:
	ButtonObserver(Controller *controller) {
		m_controller = controller;
		m_controller->AddObserver(this);
	}
	virtual ~ButtonObserver() {
		m_controller->DelObserver(this);
	}
	virtual void Update(Subject *subject) {
		if (((Controller*)subject)->GetState() == ON) {
			cout << "~ button vibration ~" << endl;
		}
	}
	void Push() {
		cout << "[Button Push]" << endl;
		m_controller->SetState(ON);
		m_controller->NotifyObserver();
	}
	void Release() {
		cout << "[Button Release]" << endl;
		m_controller->SetState(OFF);
		m_controller->NotifyObserver();
	}
private:
	Controller *m_controller;
};
 
class LEDObserver : public Observer {
public:
	LEDObserver(Controller *controller) {
		m_controller = controller;
		m_controller->AddObserver(this);
	}
	virtual ~LEDObserver() {
		m_controller->DelObserver(this);
	}
	virtual void Update(Subject *subject) {
		if (((Controller*)subject)->GetState() == ON) {
			cout << "LED ON" << endl;
		} else {
			cout << "LED OFF" << endl;
		}
	}
private:
	Controller *m_controller;
};
 
///////
void Subject::AddObserver(Observer *observer) {
	m_observers.push_back(observer);
}
 
void Subject::DelObserver(Observer *observer) {
	m_observers.push_back(observer);
}
 
void Subject::NotifyObserver() {
	list<Observer*>::iterator it = m_observers.begin();
	while (it != m_observers.end()) {
		(*it++)->Update(this);
	}
}
 
void Controller::NotifyObserver() {
	list<Observer*>::iterator it = m_observers.begin();
	while (it != m_observers.end()) {
		(*it++)->Update(this);
	}
}
 
 
/////
int main() {
	Controller *cont = new Controller;
	ButtonObserver *button = new ButtonObserver(cont);
	LEDObserver *led = new LEDObserver(cont);
 
	button->Push();
	button->Release();
 
	delete button;
	delete led;
	delete cont;
	return 0;
}
 



参考サイト

デザインパターンを“喩え話”で分かり易く理解する
http://www.netlaputa.ne.jp/~hijk/study/oo/designpattern.html



デザインパターンの骸骨たち
http://www002.upp.so-net.ne.jp/ys_oota/mdp/
最終更新:2011年12月06日 00:58