观察者模式

来源:互联网 发布:新浪微博个性域名大全 编辑:程序博客网 时间:2024/06/15 22:25

出版者+订阅者 = 观察者模式      

      观察者模式类似报纸订阅:报纸负责主题,读者是订阅者,当主题改变时,所有订阅的读者(观察者)都会收到通知,当然读者(观察者)可以退订,这样就不会再收到通知。

 

 

      主题是具有状态的对象,是这些状态的拥有者,而观察者则是状态的使用者,这种设计使得主题是真正拥有数据的人,要比许多对象控制同一份数据,要获得更加干净的OO设计。

 

 

松耦合的威力

 

      进行松耦合的两者(主题和观察者),两者虽不大清楚彼此的细节,但只要它们之间的接口依然被遵循,那么就可以自由的改变它们,而且二者都可以单独复用。这帮助我们建立富有弹性的OO系统,能够轻松的应对变化,因为两者之间的依赖降到了最低。

 

 

 

 

主题-订阅者类图

 

 

 

Java内置的观察者模式

 

      在java.util包里面包含最基本的Observer(观察者)接口与Observable类(可观察者、主题),可以利用它们使用推(push)或拉(pull)的方式传送数据。

 

  

 

如何将对象变成观察者......

      对象要成为观察者,首先要实现Observer接口,然后调用Observable对象的addObserver方法,不想再当观察者时,调用deleteObserver()方法就行了   

 

 

可观察者要如何送出通知......

 

      首先利用扩展java.util.Observable接口产生"可观察者"类,然后需要2个步骤:

        (1)、先调用setChanged()方法,标记状态已经改变的事实;

        (2)、然后调用两种notifyObservers()方法中的一个:

 

                   notifyObservers()     或    notifyObservers(Object arg)--------------当通知时,该版本可以传送任何的数据对象给每一                                                                                                                         个观察者。

 

 

观察者如何接收通知......

 

      观察者更新方法:update(Observable o,  Object  arg)  第一个参数是主题,好让观察者知道哪个主题通知它的,第二个参数正是传入notifyObservers()的数据对象,如果没有说明则为空。

 

      函数setChanged()方法用来标记状态已经改变的事实,如果调用notifyObservers()之前没有先调用setChanged(),观察者就"不会"被通知。通知后,状态改变标记被置为false。

 

如下是Observable类伪代码:

 

 

 

拉模式简单例子

 

 

import java.util.Observable;

import java.util.Observer;

public class WeatherData extends Observable {

private float temperature;

private float humidity;

private float pressure;

public WeatherData() { }

public void measurementsChanged() {

setChanged();

notifyObservers();

}

public void setMeasurements(float temperature, float humidity, float pressure) {

this.temperature = temperature;

this.humidity = humidity;

this.pressure = pressure;

measurementsChanged();

}

public float getTemperature() {

return temperature;

}

public float getHumidity() {

return humidity;

}

public float getPressure() {

return pressure;

}

}

 

 

观察者例子:

 

 

 

package headfirst.observer.weatherobservable;

 

import java.util.Observable;

import java.util.Observer;

public class CurrentConditionsDisplay implements Observer, DisplayElement {

Observable observable;

private float temperature;

private float humidity;

public CurrentConditionsDisplay(Observable observable) {

this.observable = observable;

observable.addObserver(this);

}

public void update(Observable obs, Object arg) {

if (obs instanceof WeatherData) {

WeatherData weatherData = (WeatherData)obs;

this.temperature = weatherData.getTemperature();

this.humidity = weatherData.getHumidity();

display();

}

}

public void display() {

System.out.println("Current conditions: " + temperature 

+ "F degrees and " + humidity + "% humidity");

}

}

 

 

原创粉丝点击