Head First 設計模式-C++實現---觀察者模式

1.意圖

觀察者模式(Observer Pattern):定義對象間的一種一對多依賴關係,當一個對象狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。

2. 別名

依賴(Dependents),發佈-訂閱(Publish/Subscribe)模式;

3.動機:

 降低各類緊密耦合;

Head First設計模式上的觀察者模式使用java語言實現,這裏用C++語言來實現:

Subject.h

#pragma once
#include<memory>
#include<list>
class Observer;
class Subject
{
public:
	virtual void registerObserver(Observer* obs) = 0;
	virtual void deleteObserver(Observer* obs) = 0;
	virtual void notifyObservers() = 0;
	
protected:
	std::list<Observer*> m_observers;
};

DerivedSubject.h

#pragma once
#include "Subject.h"
#include<memory>

class Observer;
class DerivedSubject : public Subject
{
public:
	DerivedSubject();
	~DerivedSubject();

	void registerObserver(Observer* obs)override;
	void deleteObserver(Observer* obs)override;
	void notifyObservers()override;

	float getTemperature();
	float getHumidity();
	float getPressure();
	//當從氣象站得到更新觀測值時, 通知觀察者
	void measurementsChanged();
	void setMesurements(float temperature, float humidity, float pressure);
private:
	float m_temperature;
	float m_humidity;
	float m_pressure;
};

Observer.h

#pragma once
class Observer
{
public:
	virtual void update(float temp, float humidity, float pressure) = 0;
	virtual ~Observer() {};
};

DisplayElement.h

#pragma once
class DisplayElement
{
	virtual void display() = 0;
};

DerivedObserver.h

#pragma once
#include "Observer.h"
#include "DisplayElement.h"
#include<memory>
class Subject;
class DerivedObservers : public Observer, public DisplayElement
{
public:
	DerivedObservers(Subject* weatherData);
	~DerivedObservers();
	void update(float temp, float humidity, float pressure)override;
	void display()override;
private :
	float m_temperature;
	float m_humidity;
	Subject* m_pWeatherData;
};

SecondObserver.h

#pragma once
#include "Observer.h"
#include "DisplayElement.h"
#include<memory>
class Subject;
class secondObserver:public Observer, public DisplayElement
{
public:
	secondObserver(Subject* obj);
	~secondObserver();
	void update(float temp, float humidity, float pressure)override;
	void display()override;
private:
	float m_temperature;
	float m_humidity;
	Subject* m_pWeatherData;
};

 

主題的實現:

DerivedSubject.cpp

#include "pch.h"
#include "DerivedSubject.h"
#include"Observer.h"

DerivedSubject::DerivedSubject()
{
}


DerivedSubject::~DerivedSubject()
{
	if(m_observers.size()>0)
		m_observers.clear();
}

void DerivedSubject::registerObserver(Observer* obs)
{
	m_observers.push_back(obs);
}
void DerivedSubject::deleteObserver(Observer* obs)
{
	m_observers.remove(obs);
}
void DerivedSubject::notifyObservers()
{
	for (auto obs : m_observers)
	{
		obs->update(m_temperature, m_humidity, m_pressure);
	}
}

float DerivedSubject::getTemperature()
{
	return 0;
}
float DerivedSubject::getHumidity()
{
	return 0;
}
float DerivedSubject::getPressure()
{
	return 0;
}
void DerivedSubject::measurementsChanged()
{
	notifyObservers();
}
void DerivedSubject::setMesurements(float temperature, float humidity, float pressure)
{
	this->m_temperature = temperature;
	this->m_humidity = humidity;
	this->m_pressure = pressure;
	measurementsChanged();
}

 

觀察者的實現

DerivedObserver.cpp

#include "pch.h"
#include "DerivedObservers.h"
#include "Subject.h"
#include <iostream>

DerivedObservers::~DerivedObservers()
{
	
}
DerivedObservers::DerivedObservers(Subject* weatherData)
{
	this->m_pWeatherData = weatherData;
	m_pWeatherData->registerObserver(this);
}

void DerivedObservers::update(float temp, float humidity, float pressure)
{
	this->m_temperature = temp;
	this->m_humidity = humidity;
	display();
}

void DerivedObservers::display()
{
	std::cout << "Current conditions: " << m_temperature << "F degrees and " << m_humidity << "% humidity" << std::endl;
}

 

SecondObserver.cpp

#include "pch.h"
#include "secondObserver.h"
#include <iostream>
#include"Subject.h"
secondObserver::secondObserver(Subject* weatherData)
{
	this->m_pWeatherData = weatherData;
	m_pWeatherData->registerObserver(this);
}


secondObserver::~secondObserver()
{
}
void secondObserver::update(float temp, float humidity, float pressure)
{
	this->m_temperature = temp;
	this->m_humidity = humidity;
	display();
}

void secondObserver::display()
{
	std::cout << "second conditions: " << m_temperature << "F degrees and " << m_humidity << "% humidity" << std::endl;
}

 

main.cpp

#include "pch.h"
#include <iostream>
#include "DerivedObservers.h"
#include "DerivedSubject.h"
#include"Observer.h"
#include"secondObserver.h"

int main()
{
	DerivedSubject* weatherData =new DerivedSubject;
	Observer* obj = new DerivedObservers(weatherData);
	Observer* sobj = new secondObserver(weatherData);
	weatherData->setMesurements(80, 65, 30.4f);
	weatherData->setMesurements(82, 70, 29.2f);
	weatherData->setMesurements(78, 90, 29.2f);
	std::cout << "------------------delete observer-------------------------" << std::endl;
	weatherData->deleteObserver(obj);
	weatherData->setMesurements(58, 40, 19.2f);
	system("pause");
}

 

輸出:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章