zoukankan      html  css  js  c++  java
  • 观察者模式

    目的:用WeatherData对象从气象台取得数据并更新布告板,考虑系统的可扩展性,满足随心所欲添加或删除布告板。如图所示:

    考虑在同一时刻只选择一个布告板并显示的情况。抽取中其中改变的部分,即布告板。设想实现如下图:

    上图设计中可以满足弹性的任意选择一个布告板并对其进行更新。然而我们需要的是有多个布告板能显示不同的

    内容并显示更新。解决问题的方法:WeatherData中需要有一个容器来缓存多个布告板,但是并不是所有的布告

    板都需要进行更新显示。WeatherData只对那些有需要更新并显示的布告板进行通知并更新他们。所以引出了观察

    者模式,这相当于一个订阅问题,每个布告板都是一个观察者,Weather是一个主题。观察者对主题感兴趣则对主题

    进行订阅。当观察者对主题不再感兴趣时者取消订阅主题,即做到了任意添加或删除布告板。当主题改变时,所有订

    阅主题的观察者都将被通知。

    实现图如下:

    实现代码:

    主题接口:

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

      

    观察者接口:

    public interface Observer {
    public void update(float temperature,float pressure,float humidy);
    public void register(Subject weatherData);
    public void cancel();
    }
    

      

    显示接口:

    public interface DisplayElement {
    public void display();
    }
    

      

    WeatherData类:

    public class WeatherData implements Subject{
    private float temperature;
    private float pressure;
    private float humidy;
    private List observers;
    public WeatherData(){
    observers=new ArrayList();
    }
    @Override
    public void registerObserver(Observer o) {
    // TODO Auto-generated method stub
    observers.add(o);
    }
    @Override
    public void removeObserver(Observer o) {
    // TODO Auto-generated method stub
    observers.remove(o);
    }
    @Override
    public void notifyObservers() {
    // TODO Auto-generated method stub
    for(int i=0;i<observers.size();i++)
    {
    Observer o=(Observer)observers.get(i);
    o.update(temperature,pressure,humidy);
    }
    }
    public void measurementsChanged()
    {
    notifyObservers();
    }
    public void setMeasurements(float temperature,float pressure,float humidy)
    {
    this.temperature=temperature;
    this.pressure=pressure;
    this.humidy=humidy;
    measurementsChanged();
    }
    
    }
    

      

    布告板1:

    public class CurrentConditionDisplay implements Observer, DisplayElement{
    private float temperature;
    private float pressure;
    private float humidy;
    private Subject weatherData;
    
    public CurrentConditionDisplay()
    {}
    public CurrentConditionDisplay(Subject weatherData)
    {
    this.weatherData=weatherData;
    weatherData.registerObserver(this);
    }
    @Override
    public void display()
    {
    // TODO Auto-generated method stub
    System.out.println("Current conditions: ");
    System.out.println(temperature+"F degrees");
    System.out.println(pressure+"%pressure");
    System.out.println(humidy+"%humidy");
    }
    @Override
    public void update(float temperature,float pressure,float humidy)
    {
    // TODO Auto-generated method stub
    this.temperature=temperature;
    this.pressure=pressure;
    this.humidy=humidy;
    display();
    }
    @Override
    public void register(Subject weatherData) {
    // TODO Auto-generated method stub
    this.weatherData=weatherData;
    weatherData.registerObserver(this);
    }
    @Override
    public void cancel() {
    // TODO Auto-generated method stub
    weatherData.removeObserver(this);
    }
    
    }
    

      

    布告板2:

    public class AverageConditionDisplay implements Observer,DisplayElement{
    private float temperature;
    private float pressure;
    private float humidy;
    Subject weatherData;
    public AverageConditionDisplay()
    {}
    public AverageConditionDisplay(Subject weatherData)
    {
    this.weatherData=weatherData;
    weatherData.registerObserver(this);
    }
    
    @Override
    public void display() {
    // TODO Auto-generated method stub
    System.out.println("average conditions: ");
    System.out.println(temperature+"F degrees");
    System.out.println(pressure+"%pressure");
    System.out.println(humidy+"%humidy");
    }
    
    @Override
    public void update(float temperature, float pressure, float humidy) {
    // TODO Auto-generated method stub
    if(this.temperature==0)
    {
    this.temperature=temperature;
    }
    else 
    {
    this.temperature=(this.temperature+temperature) / 2;
    }
    if(this.pressure==0)
    {
    this.pressure=pressure;
    }
    else
    {
    this.pressure=(this.pressure+pressure) / 2;
    }
    if(this.humidy==0)
    {
    this.humidy=humidy;
    }
    else
    {
    this.humidy=(this.humidy+humidy) / 2;
    }
    display();
    }
    
    @Override
    public void register(Subject weatherData) {
    // TODO Auto-generated method stub
    this.weatherData=weatherData;
    weatherData.registerObserver(this);
    }
    
    @Override
    public void cancel() {
    // TODO Auto-generated method stub
    weatherData.removeObserver(this);
    }
    
    }
    

      

    气象模拟类:

    public class WeatherStation {
    public static void main(String [] args)
    {
    WeatherData weatherData=new WeatherData();
    //CurrentConditionDisplay ccd=new CurrentConditionDisplay(weatherData);
    //AverageConditionDisplay acd=new AverageConditionDisplay(weatherData);
    CurrentConditionDisplay ccd=new CurrentConditionDisplay();
    ccd.register(weatherData);
    AverageConditionDisplay acd=new AverageConditionDisplay();
    acd.register(weatherData);
    weatherData.setMeasurements(80, 30.4f, 65);
    weatherData.setMeasurements(60, 28.2f, 35);
    //weatherData.removeObserver(acd);
    acd.cancel();
    weatherData.setMeasurements(90, 32.4f, 62);
    }
    }
    

      

  • 相关阅读:
    [算法] 堆栈
    [刷题] PTA 02-线性结构3 Reversing Linked List
    java IO流 (八) RandomAccessFile的使用
    java IO流 (七) 对象流的使用
    java IO流 (六) 其它的流的使用
    java IO流 (五) 转换流的使用 以及编码集
    java IO流 (四) 缓冲流的使用
    java IO流 (三) 节点流(或文件流)
    java IO流 (二) IO流概述
    java IO流 (一) File类的使用
  • 原文地址:https://www.cnblogs.com/yanglf/p/3885425.html
Copyright © 2011-2022 走看看