HeadFirst設計模式-觀察者模式

觀察者模式:定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,他的所有依賴者都會收到通知並自動更新。

 

 

 

Java代碼

package b_ObserverPattern._02_weatherstation;

public interface Subject {
    public void registerObserver(Observer o) ;
    public void removeObserver(Observer o);
    public void notifyObserver();

}
//-------------------------------------
package b_ObserverPattern._02_weatherstation;

public interface Observer {
    public void update(float temp, float humidity, float pressure);

}

//-------------------------------------
package b_ObserverPattern._02_weatherstation;

public class CurrentConditionsDisplay implements Observer, DisplayElement {
    
    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    public CurrentConditionsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }

}

//-------------------------------------
package b_ObserverPattern._02_weatherstation;

public class ForecastDisplay implements DisplayElement, Observer {

    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    public ForecastDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    
    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }

    @Override
    public void display() {
        System.out.println("根據溫度溼度預測天氣。。。");
    }

}

//------------------------------
package b_ObserverPattern._02_weatherstation;

public class StatisticsDisplay implements DisplayElement, Observer {
    
    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    public StatisticsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }

    @Override
    public void display() {
        System.out.println("統計最大值、最小值、平均值");
    }

}

//---------------------------------
package b_ObserverPattern._02_weatherstation;

public interface DisplayElement {
    public void display();
}


//-------------------------------------
package b_ObserverPattern._02_weatherstation;

import java.util.ArrayList;

public class WeatherDate implements Subject {
    
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;
    
    public WeatherDate() {
        observers = new ArrayList();
    }

    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if(i>=0) {
            observers.remove(i);
        }

    }

    @Override
    public void notifyObserver() {
//        for (int i = 0; i < observers.size(); i++) {
//            
//        }
        for (Object object : observers) {
            Observer observer = (Observer)object;
            observer.update(temperature, humidity, pressure);
        }
    }
    
    public void measurementsChanged() {
        notifyObserver();
    }
    
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }

}

//-------------------------------------
package b_ObserverPattern._02_weatherstation;

public class WeatherStation {

    public static void main(String[] args) {
        WeatherDate weatherData = new WeatherDate();
        CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
        Observer statisticsDisplay = new StatisticsDisplay(weatherData);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
        
        weatherData.setMeasurements(80, 65, 30.4f);
        weatherData.setMeasurements(82, 76, 32.9f);
        weatherData.setMeasurements(81, 70, 31.7f);
    }

}
View Code

 

 

c++代碼

#pragma once

#include "Observer.h"

class Subject
{
public:
    virtual void registerObserver(Observer* o) = 0;
    virtual void removeObserver(Observer* o) = 0;
    virtual void notifyObserver() = 0;
};

//-----------------------------------------
#pragma once
#include <iostream>
#include <string>

using namespace std;

class Observer
{
public:
    virtual void update(string arg) = 0;
};


//-----------------------------------------
#pragma once
#include "Observer.h"
#include "Subject.h"
class CurrentConditionsDisplay :
    public Observer
{
    Subject* subject;
public:

    CurrentConditionsDisplay(Subject* sub)
    {
        subject = sub;
        subject->registerObserver(this);
    }

    ~CurrentConditionsDisplay()
    {
    }

    void update(string arg)
    {
        
        cout << "CurrentConditionsDisplay arg:" << arg << '\n';
    }
};


//-----------------------------------------
#pragma once
#include "Observer.h"
#include "Subject.h"

class ForecastDisplay :
    public Observer
{
    Subject* subject;
public:

    ForecastDisplay(Subject* sub)
    {
        subject = sub;
        subject->registerObserver(this);
    }

    ~ForecastDisplay()
    {
    }

    void update(string arg)
    {
        cout << "ForecastDisplay arg:" << arg << '\n';
    }
};


//-----------------------------------------
#pragma once
#include "Observer.h"
#include "Subject.h"

class StatisticsDisplay :
    public Observer
{
    Subject* subject;
public:

    StatisticsDisplay(Subject* sub)
    {
        subject = sub;
        subject->registerObserver(this);
    }

    ~StatisticsDisplay()
    {
    }

    void update(string arg)
    {
        cout << "StatisticsDisplay arg:" << arg << '\n';
    }
};


//-----------------------------------------
#pragma once
#include "Subject.h"
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

class WeatherData :
    public Subject
{
    string temperature;
    string humidity;
    string pressure;

    vector<Observer*> observers;
public:

    WeatherData()
    {
    }

    ~WeatherData()
    {
    }

    void registerObserver(Observer* o)
    {
        observers.push_back(o);
    }

    void removeObserver(Observer* o)
    {
        observers.erase(remove(observers.begin(), observers.end(), o));
    }

    void notifyObserver()
    {
        for (int i = 0; i < observers.size(); i++)
        {
            Observer* pObj = observers.at(i);
            string arg = this->temperature + ";" + this->humidity + ";" + this->pressure;
            pObj->update(arg);
        }
    }


    void measurementsChanged() {
        notifyObserver();
    }

    void setMeasurements(float temperature, float humidity, float pressure) {
        this->temperature = to_string(temperature);
        this->humidity = to_string(humidity);
        this->pressure = to_string(pressure);
        measurementsChanged();
    }

};


//-----------------------------------------
#include <iostream>
#include "CurrentConditionsDisplay.h"
#include "ForecastDisplay.h"
#include "StatisticsDisplay.h"
#include "WeatherData.h"

using namespace std;

int main()
{
    WeatherData data;
    
    CurrentConditionsDisplay d1(&data);
    ForecastDisplay d2(&data);
    StatisticsDisplay d3(&data);

    data.setMeasurements(13.2, 23, 31);
    data.setMeasurements(15.2, 28, 71);
    data.removeObserver(&d2);
    data.setMeasurements(17.2, 21, 61);

    return 0;
}
//-----------------------------------------
View Code

 

 

****

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