zoukankan      html  css  js  c++  java
  • 设计模式

    观察者模式(Observer Pattern) 详细说明


    本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157


    版权全部, 禁止转载, 如有转载, 请站内联系.


    观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的全部依赖者都会收到通知并自己主动更新.


    用法:


    1. 首先新建主题(subject)接口, 负责注冊(register)删除(remove)通知(notify)观察者; 观察者(observer)接口, 负责更新(update)数据;

    主题(subject)接口: 注冊观察者(registerObserver), 删除观察者(removeObserver), 通知观察者(notifyObservers, 通知全部观察者);

    观察者(observer)接口: 更新(update);


    代码:

    /**
     * @time 2014年5月22日
     */
    package observer;
    
    /**
     * @author C.L.Wang
     *
     */
    public interface Subject {
    	public void registerObserver(Observer o);
    	public void removeObserver(Observer o);
    	public void notifyObervers();
    }
    
    
    /**
     * @time 2014年5月22日
     */
    package observer;
    
    /**
     * @author C.L.Wang
     *
     */
    public interface Observer {
    	public void update(float temp, float humidity, float pressure);
    }
    
    
    /**
     * @time 2014年5月22日
     */
    package observer;
    
    /**
     * @author C.L.Wang
     *
     */
    public interface DisplayElement {
    	public void display();
    }
    

    2. 实现主题(subject)接口, 通过列表(list)的形式注冊(register)和删除(remove)观察者, 

    通知(notify)观察者时, 循环调用全部已注冊的观察者的更新(update)动作;

    通过接口函数(set), 封装通知(notify)动作, 传入參数并进行通知.


    代码:

    /**
     * @time 2014年5月22日
     */
    package observer;
    
    import java.util.ArrayList;
    
    /**
     * @author C.L.Wang
     *
     */
    public class WeatherData implements Subject {
    	
    	public ArrayList<Observer> observers;
    	private float temperature;
    	private float humidity; //湿度
    	private float pressure;
    	
    	public WeatherData() {
    		observers = new ArrayList<Observer>();
    	}
    	
    	/* (non-Javadoc)
    	 * @see observer.Subject#registerObserver(observer.Observer)
    	 */
    	@Override
    	public void registerObserver(Observer o) {
    		// TODO Auto-generated method stub
    		observers.add(o);
    	}
    
    	/* (non-Javadoc)
    	 * @see observer.Subject#removeObserver(observer.Observer)
    	 */
    	@Override
    	public void removeObserver(Observer o) {
    		// TODO Auto-generated method stub
    		int i = observers.indexOf(o);
    		if (i>=0) {
    			observers.remove(i);
    		}
    	}
    
    	/* (non-Javadoc)
    	 * @see observer.Subject#notifyObervers()
    	 */
    	@Override
    	public void notifyObervers() {
    		// TODO Auto-generated method stub
    		for (int i=0; i<observers.size(); ++i) {
    			Observer observer = (Observer)observers.get(i);
    			observer.update(temperature, humidity, pressure);
    		}
    	}
    	
    	public void measurementsChanged() {
    		notifyObervers();
    	}
    	
    	public void setMeasurements(float temperature, float humidity, float pressure) {
    		this.temperature = temperature;
    		this.humidity = humidity;
    		this.pressure = pressure;
    		measurementsChanged();
    	}
    
    }
    

    3. 实现观察者(observer)接口, 主要保存收到的数据, 并实现更新(update)动作, 即把数据保存在本地;

    构造函数中, 把自己注冊(register)入, 传入的主题(subject)參数, 使主题能够通知观察者.


    代码:

    /**
     * @time 2014年5月22日
     */
    package observer;
    
    /**
     * @author C.L.Wang
     *
     */
    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);
    	}
    	
    	/* (non-Javadoc)
    	 * @see observer.DisplayElement#display()
    	 */
    	@Override
    	public void display() {
    		// TODO Auto-generated method stub
    		System.out.println("Current conditions: " + temperature +
    				"F degrees and " + humidity + "% humidity");
    	}
    
    	/* (non-Javadoc)
    	 * @see observer.Observer#update(float, float, float)
    	 */
    	@Override
    	public void update(float temperature, float humidity, float pressure) {
    		// TODO Auto-generated method stub
    		this.temperature = temperature;
    		this.humidity = humidity;
    		display();
    	}
    
    }
    
    
    package observer;
    
    import java.util.*;
    
    public class ForecastDisplay implements Observer, DisplayElement {
    	private float currentPressure = 29.92f;  
    	private float lastPressure;
    	private WeatherData weatherData;
    
    	public ForecastDisplay(WeatherData weatherData) {
    		this.weatherData = weatherData;
    		weatherData.registerObserver(this);
    	}
    
    	public void update(float temp, float humidity, float pressure) {
                    lastPressure = currentPressure;
    		currentPressure = pressure;
    
    		display();
    	}
    
    	public void display() {
    		System.out.print("Forecast: ");
    		if (currentPressure > lastPressure) {
    			System.out.println("Improving weather on the way!");
    		} else if (currentPressure == lastPressure) {
    			System.out.println("More of the same");
    		} else if (currentPressure < lastPressure) {
    			System.out.println("Watch out for cooler, rainy weather");
    		}
    	}
    }
    
    
    package observer;
    
    import java.util.*;
    
    public class StatisticsDisplay implements Observer, DisplayElement {
    	private float maxTemp = 0.0f;
    	private float minTemp = 200;
    	private float tempSum= 0.0f;
    	private int numReadings;
    	private WeatherData weatherData;
    
    	public StatisticsDisplay(WeatherData weatherData) {
    		this.weatherData = weatherData;
    		weatherData.registerObserver(this);
    	}
    
    	public void update(float temp, float humidity, float pressure) {
    		tempSum += temp;
    		numReadings++;
    
    		if (temp > maxTemp) {
    			maxTemp = temp;
    		}
     
    		if (temp < minTemp) {
    			minTemp = temp;
    		}
    
    		display();
    	}
    
    	public void display() {
    		System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)
    			+ "/" + maxTemp + "/" + minTemp);
    	}
    }
    

    4. 測试, 创建不同的观察者(observer), 并把主题(subject)作为參数传入, 通知观察者.


    代码:

    /**
     * @time 2014年5月22日
     */
    package observer;
    
    /**
     * @author C.L.Wang
     *
     */
    public class WeatherStation {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		WeatherData weatherData = new WeatherData();
    		
    		CurrentConditionsDisplay currentConditionsDisplay = 
    				new CurrentConditionsDisplay(weatherData); //new的时候进行注冊
    		
    		StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
    		ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
    		
    		weatherData.setMeasurements(80, 65, 30.4f);
    		weatherData.setMeasurements(82, 70, 29.2f);
    		weatherData.setMeasurements(78, 90, 29.2f);
    	}
    
    }
    

    5. 输出:

    Current conditions: 80.0F degrees and 65.0% humidity
    Avg/Max/Min temperature = 80.0/80.0/80.0
    Forecast: Improving weather on the way!
    Current conditions: 82.0F degrees and 70.0% humidity
    Avg/Max/Min temperature = 81.0/82.0/80.0
    Forecast: Watch out for cooler, rainy weather
    Current conditions: 78.0F degrees and 90.0% humidity
    Avg/Max/Min temperature = 80.0/82.0/78.0
    Forecast: More of the same
    


    面向对象的原则:

    为了设计对象和工作之间松散耦合的交互.





  • 相关阅读:
    腾讯云CDN python SDK
    GLFW初体验
    Mac使用Xcode配置openGL
    sklearn神经网络分类
    sklearn LDA降维算法
    sklearn CART决策树分类
    sklearn逻辑回归
    抢占式内核与非抢占式内核
    操作系统原理学习笔记--进程管理
    操作系统原理4——存储管理
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/5032382.html
Copyright © 2011-2022 走看看