行为型模式-观察者模式(Observer)

来源:互联网 发布:谷得网络这家公司怎样 编辑:程序博客网 时间:2024/05/16 06:03

一:定义:

Observer:Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

二:引入

一个气象观测站的例子:

 

 

public class WeatherData {
    
private CurrentConditionsDisplay currentConditionsDisplay;
    
private ForecastDisplay forecastDisplay;
    
private StatisticsDisplay statisticsDisplay;
    
public WeatherData(CurrentConditionsDisplay currentConditionsDisplay,ForecastDisplay forecastDisplay,StatisticsDisplay statisticsDisplay)
    
{
        
this.currentConditionsDisplay=currentConditionsDisplay;
        
this.forecastDisplay=forecastDisplay;
        
this.statisticsDisplay=statisticsDisplay;
    }

    
public void mesurementsChanged()
    
{
        
float temp=getTemperature();
        
float humidity=getHumidity();
        
float pressure=getPressure();
        
        currentConditionsDisplay.update(temp,humidity,pressure);
        forecastDisplay.update(temp,humidity,pressure);
        statisticsDisplay.update(temp,humidity,pressure);
    }

    
    
public float getTemperature()
    
{
        
return 30;
    }

    
    
public float getHumidity()
    
{
        
return 60;
    }

    
    
public float getPressure()
    
{
        
return 78;
    }

}




public class CurrentConditionsDisplay extends Display {
    
public  void update(float temp,float humidity,float pressure)
    
{
        System.out.println(
"CurrentConditionsDisplay  temp="+temp+",humidity="+humidity+",pressure="+pressure);
    }

}



public class Client {

    
public static void main(String[] args) {
         CurrentConditionsDisplay currentConditionsDisplay
=new CurrentConditionsDisplay();
         ForecastDisplay forecastDisplay
=new ForecastDisplay();
         StatisticsDisplay statisticsDisplay
=new StatisticsDisplay();
         
         WeatherData weatherData
=new WeatherData(currentConditionsDisplay,forecastDisplay,statisticsDisplay);
         weatherData.mesurementsChanged();
    }


}


问题:

耦合太紧,如果增加新的Display,需修改接口和实现。

observer模式:

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


public class WeatherData implements Subject {
    
private List observerList=new ArrayList();
    
private float temperature;
    
private float humidity;
    
private float pressure;

    
public WeatherData(float temperature,float humidity,float pressure)
    
{
        
this.temperature=temperature;
        
this.humidity=humidity;
        
this.pressure=pressure;
    }

    
public void mesurementsChanged()
    
{
        notifyObservers();
        
    }

        
    
public void registerObserver(Observer observer) {
        observerList.add(observer);
        
    }

    
public void removeObserver(Observer observer) {
        observerList.remove(observer);        
    }

    
    
public void notifyObservers() {
        
for(Iterator iter=observerList.iterator();iter.hasNext();)
        
{
            Observer observer
=(Observer)iter.next();
            observer.update(temperature,humidity,pressure);
        }

        
    }

    
public float getHumidity() {
        
return humidity;
    }

    
public void setHumidity(float humidity) {
        
this.humidity = humidity;
    }

    
public float getPressure() {
        
return pressure;
    }

    
public void setPressure(float pressure) {
        
this.pressure = pressure;
    }

    
public float getTemperature() {
        
return temperature;
    }

    
public void setTemperature(float temperature) {
        
this.temperature = temperature;
    }
    
}


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


public class CurrentConditionsDisplay implements Observer {
    
public  void update(float temp,float humidity,float pressure)
    
{
        System.out.println(
"CurrentConditionsDisplay  temp="+temp+",humidity="+humidity+",pressure="+pressure);
    }

}


public class Client {

    
public static void main(String[] args) {
        WeatherData weatherData
=new WeatherData(30,50,60);
        Observer currentConditionsDisplay
=new CurrentConditionsDisplay();
        weatherData.registerObserver(currentConditionsDisplay);
        weatherData.mesurementsChanged();
        Observer statisticsDisplay
=new StatisticsDisplay();
        weatherData.registerObserver(statisticsDisplay);
        
        System.out.println(
"-------------");
        weatherData.mesurementsChanged();
        weatherData.removeObserver(currentConditionsDisplay);
        
        System.out.println(
"-------------");
        weatherData.mesurementsChanged();
    }

}

 

 

java对Observer模式的支持:

Observable相当于我们上面的Subject,Observer对Observer。对非业务部分方法进行了实现。

package java.util;
public class Observable {
    
private boolean changed = false;
    
private Vector obs;

    
public Observable() {
    obs 
= new Vector();
    }

    
    
public synchronized void addObserver(Observer o) {
        
if (o == null)
            
throw new NullPointerException();
    
if (!obs.contains(o)) {
        obs.addElement(o);
    }

    }

    
    
public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    
    
public void notifyObservers(Object arg) {

        Object[] arrLocal;

    
synchronized (this{

        
if (!changed)
                
return;
            arrLocal 
= obs.toArray();
            clearChanged();
        }


        
for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(
this, arg);
    }

}
 

package java.util;

public interface Observer {

    
void update(Observable o, Object arg);
}

 

 气象站例子对应Java版实现:

public class WeatherData extends Observable {

    
private float temperature;
    
private float humidity;
    
private float pressure;
    
public WeatherData(float temperature,float humidity,float pressure)
    
{
        
this.temperature=temperature;
        
this.humidity=humidity;
        
this.pressure=pressure;
    }

    
public void mesurementsChanged()
    
{
        setChanged();
        notifyObservers();
        
    }

    
public float getHumidity() {
        
return humidity;
    }

    
public void setHumidity(float humidity) {
        
this.humidity = humidity;
    }

    
public float getPressure() {
        
return pressure;
    }

    
public void setPressure(float pressure) {
        
this.pressure = pressure;
    }

    
public float getTemperature() {
        
return temperature;
    }

    
public void setTemperature(float temperature) {
        
this.temperature = temperature;
    }

}


public class CurrentConditionsDisplay implements Observer {


    
public void update(Observable o, Object arg) {
        
if (o instanceof WeatherData)
        
{
            WeatherData weatherData
=(WeatherData)o;
            System.out.println(
"CurrentConditionsDisplay  temp="+weatherData.getTemperature()+",humidity="+weatherData.getHumidity()+",pressure="+weatherData.getPressure());
        }

        
    }

}



public class Client {

    
public static void main(String[] args) {
        WeatherData weatherData
=new WeatherData(34,44,65);
        Observer currentConditionsDisplay
=new CurrentConditionsDisplay();
        weatherData.addObserver(currentConditionsDisplay);
        weatherData.mesurementsChanged();
        Observer statisticsDisplay
=new StatisticsDisplay();
        weatherData.addObserver(statisticsDisplay);
        
        System.out.println(
"-------------");
        System.out.println(weatherData.countObservers());
        weatherData.mesurementsChanged();

        System.out.println(
"-------------");
        System.out.println(weatherData.countObservers());
        weatherData.mesurementsChanged();
    }

}

 

三:结构    

四:实际应用

  1.  

 

五:适用情形

Use the Observer pattern in any of the following situations:

  • When an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently.

     

  • When a change to one object requires changing others, and you don't know how many objects need to be changed.

     

  • When an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these objects tightly coupled.

参考文献:
1:阎宏,《Java与模式》,电子工业出版社
2:Eric Freeman & Elisabeth Freeman,《Head First Design Pattern》,O'REILLY
3:GOF,《designpatterns-elements.of.reuseable.object-oriented.software》

        
原创粉丝点击