在java API中有内置的观察者模式,在java.util包中有Observer接口和observalbe类,分别对应观察者和主题。java API内置观察者模式支持以push和pull方式传输数据。
Observer : 是一个接口,观察者可实现此接口来得到Observalbe对象更改通知。只含有update方法。
void update(Observable o,Object arg)
说明:
只要改变了 observable 对象就调用此方法。应用程序调用 Observable 对象的 notifyObservers 方法,以便向所有该对象的观察者通知此改变。
参数:
o - observable 对象。
arg - 传递给 notifyObservers 方法的参数。
Observable:对应观察者模式中的主题类,当一个observalbe实例改变后,调用observalbe的notifyObservers方法的应用程序会通过调用观察者的update方法通知观察者该实例发生变化。
protected void setChanged()
说明
标记此 Observable 对象为已改变的对象;现在 hasChanged 方法将返回 true。
protected void clearChanged()
说明:
指示对象不再改变,或者它已对其所有的观察者通知了最近的改变,所以 hasChanged 方法将返回 false。notifyObservers 方法自动调用此方法。
public boolean hasChanged()
说明:
测试对象是否改变。
返回:
当且仅当在此对象上最近调用了 setChanged 方法,而不是 clearChanged 方法时,才返回 true;否则返回 false。
以上三个方法可以让主题对象更新推送通知时,有更多的灵活性,用户可以通过自己业务需求调用setChanged方法,进行有效更新。
public void notifyObservers(Object arg)
说明:
如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。
每个观察者都有其 update 方法,其调用参数有两个:observable 对象和 arg 参数。
参数:
arg - 任意对象。
以推的方式,更新通知,通过参数arg传递更新的数据
public void notifyObservers()
说明:
如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。
每个观察者都有其 update 方法,其调用参数有两个:observable 对象和 null。换句话说,此方法等效于:
notifyObservers(null)
以拉的方式,更新通知。在主题对象中通过getter方法,观察者可以获取自己想要的信息。
java内置观察者模式实例:
主题代码:
import java.util.Observable;
public class WeatherData extends Observable {
private float temperature;
private float pressure;
public WeatherData(){}
public void measurementsChanged()
{
setChanged();
notifyObservers();
}
public void setMeatherments(float temperature,float pressure)
{
this.temperature = temperature;
this.pressure = pressure;
measurementsChanged();
}
public float getPressure() {
return pressure;
}
public float getTemperature() {
return temperature;
}
}
观察者代码:
import java.util.Observable;
import java.util.Observer;
public class PressureDisplay implements Observer {
Observable observable;
private float pressure;
public PressureDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof WeatherData)
{
WeatherData weatherData = (WeatherData)o;
this.pressure = weatherData.getPressure();
display();
}
}
public void display()
{
System.out.println("current temperature is" + pressure);
}
}
测试代码:
public class ObserverTest {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
TemperatureDisplay temperatureDisplay = new TemperatureDisplay(weatherData);
PressureDisplay pressureDisplay = new PressureDisplay(weatherData);
weatherData.setMeatherments(30.8f, 70.9f);
}
}
内置对象缺点:
Observable是一个超类,这就让我们必须设计一个子类继承它,但是如果想让子类具有Observable类和其他超类的行为,就会陷入尴尬,因为java不支持多重继承。而且Observable的某些方法都是protected类型,因此除非继承此类,否则无法使用这些方法。
违反 " 多用组合,少用继承" 的设计原则