headfirst设计模式第二章读书笔记--观察者模式

思想
观察者模式是使用的比较普遍的设计模式,其核心思想是在被观察者(Observable/Subject)中放入观察者(Observer)的实例列表,一旦被观察者有数据更新,则遍历观察者列表,调用观察者方法来更新数据。

下面举个例子:比如一家气象站有气象数据,拥有历史 当前和未来数天的天气数据,现在要将这些数据显示到天气布告板上去,但是,布告板有详细的布告板也有简单的布告板,总之,数据可能给布告板的都是相同,但是布告板可能显示成不同的样子,或者布告板只取它需要的数据显示。这个例子可以用观察者模式来实现。

天气站实现

headfirst设计模式第二章读书笔记--观察者模式_第1张图片

 

headfirst设计模式第二章读书笔记--观察者模式_第2张图片

DisplayElement.java

package observer;

public interface DisplayElement {
   public void display();   //布告板显示
}

 

Observer.Java

package observer;

public interface Observer {
   public void update(float temp,float humidity,float pressure); //状态改变时调用
}

 

CurrentCondtionsDisplay.Java

package subject;

import java.util.ArrayList;

import observer.DisplayElement;
import observer.Observer;

public class CurrentConditionsDisplay implements Observer,DisplayElement{
    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    public CurrentConditionsDisplay( Subject weatherData) {     //注册
        // TODO Auto-generated constructor stub
        this.weatherData = weatherData;
        weatherData.resisterObserver(this);
    }
    
    

    @Override
    public void update(float temp, float humidity, float pressure) {
        // TODO Auto-generated method stub
       this.temperature = temperature;
       this.humidity = humidity;
       display();
    }
    
    @Override
    public void display() {
        // TODO Auto-generated method stub
         System.out.println("temperature:" + temperature + " humidity:"+humidity);    
    }
}

 

Subject.Java

package subject;

import observer.Observer;

public interface Subject {
    public void resisterObserver(Observer o);  //加入成为观察者
    public void removeObserver(Observer o);    //从观察者退出
    public void notifyObserver();              //主题状态改变时方法调用,通知所有观察者
}

 

WeatherData.Java

package subject;

import java.util.ArrayList;

import observer.Observer;

public class WeatherData implements Subject{
      private ArrayList observers;
      private float temperature;
      private float humidity;
      private float pressure;
      public WeatherData() {
        // TODO Auto-generated constructor stub
          observers = new ArrayList();
    }
      
      @Override
    public void resisterObserver(Observer o) {   //加入
        // TODO Auto-generated method stub
           observers.add(o);
    }
      
      @Override
    public void removeObserver(Observer o) {  //删除
        // TODO Auto-generated method stub
        int i = observers.indexOf(o);
        if(i >= 0) {
            observers.remove(i);
        }
    }
      
    @Override
    public void notifyObserver() {   //对观察者一个一个跟新
        // TODO Auto-generated method stub
           for(int i = 0;ii){
               Observer observer = (Observer)observers.get(i);
               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();
    }

    
}

 

Test.Java

package test;

import subject.CurrentConditionsDisplay;
import subject.WeatherData;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        WeatherData weatherData = new WeatherData();
        
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
        weatherData.setMeasurements(80.0f, 69.0f, 30.4f);
    }

}

 

结果

总结

JAVA API的观察者模式的实现虽然减少了不少代码,但是也存在诸多扩展和灵活性问题。如果JAVA API提供的方式已经够用,那么就可以使用简便的JAVA API方式,但是如果觉得程序后期需要扩展的可能性大,那么最好还是不要闲麻烦,自己实现一下。对比之前的总结,我觉得还是当前这个版本比较通俗易懂。

在Java和Android系统中,观察者模式的例子很常见,比如Swing组件和Android Button控件的点击事件监听。Android 的广播和广播接收者,也是利用注册和解除注册来实现接收广播的,至少形式上很相似。
这就像从报社订报纸,每个用户可以选择定或者不定报纸。报社每月会遍历订阅用户列表,给他们寄去报纸;如果用户中途取消订阅,报社就删除该用户,下次不再寄去报纸。其他没有订阅的用户如果感兴趣了,也可以订阅,报社会在列表加入该用户,下次寄去报纸给该用户。

适用场景

1.当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化

2.如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该有多少对象需要被连带改变

3.当一个对象必须通知其他的对象,但是你又希望这个对象和其他的被通知的对象是松散耦合的

 

 

 

你可能感兴趣的:(headfirst设计模式第二章读书笔记--观察者模式)