觀察者模式(發佈訂閱模式):在對象之間定義一對多的依賴,這樣一來,當一個對象改變狀態,依賴他的對象都會收到通知,並自動更新。java
使用場景:當一個對象狀態改變同時須要改變其餘對象,且不知道多少觀察者受影響。ide
觀察者模式包含如下幾個主要部分:this
觀察者模式中,爲分爲拉模型和推模型。code
public interface DisplayElement { public void display(); }
public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); }
public interface Observer { public void update(float temperate,float humidity,float pressure); }
public class WeatherData implements Subject { private ArrayList<Observer> observers; private float temperate; private float humidity; private float pressure; public WeatherData(){ observers = new ArrayList<Observer>(); } @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 int i = observers.indexOf(o); if(i >= 0) { observers.remove(i); } } @Override public void notifyObservers() { // TODO Auto-generated method stub for (int i = 0; i < observers.size(); i++) { Observer observer =observers.get(i); observer.update(temperate, humidity, pressure); } } public void measurementsChanged(){ notifyObservers(); } public void setMeasurements(float temperate,float humidity,float pressure){ this.temperate = temperate; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } }
public class CurrentConditionDisplay2 implements Observer,DisplayElement{ private float temperate; private float humidity; private Observable observable; public CurrentConditionDisplay2(Observable weatherData) { this.observable = weatherData; this.observable.addObserver(this); } @Override public void display() { // TODO Auto-generated method stub System.out.println("Current conditions:"+temperate +" F degrees and "+humidity+" % humidity"); } @Override public void update(Observable o, Object arg) { // TODO Auto-generated method stub if (o instanceof WeatherData2) { WeatherData2 weatherData2 = (WeatherData2) o; this.humidity = weatherData2.getHumidity(); this.temperate = weatherData2.getTemperate(); display(); } } }
public class WeatherData2 extends Observable { private float temperate; private float humidity; private float pressure; public WeatherData2(){ } public void measurementsChanged(){ setChanged(); notifyObservers(); } public void setMeasurements(float temperate,float humidity,float pressure){ this.temperate = temperate; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } public float getTemperate() { return temperate; } public void setTemperate(float temperate) { this.temperate = temperate; } 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 class CurrentConditionDisplay2 implements Observer,DisplayElement{ private float temperate; private float humidity; private Observable observable; public CurrentConditionDisplay2(Observable weatherData) { this.observable = weatherData; this.observable.addObserver(this); } @Override public void display() { // TODO Auto-generated method stub System.out.println("Current conditions:"+temperate +" F degrees and "+humidity+" % humidity"); } @Override public void update(Observable o, Object arg) { // TODO Auto-generated method stub if (o instanceof WeatherData2) { WeatherData2 weatherData2 = (WeatherData2) o; this.humidity = weatherData2.getHumidity(); this.temperate = weatherData2.getTemperate(); display(); } } }
以上兩個例子中,推模式是用自定義接口,拉模式使用java內置觀察者模式,拉/推模式均可以用自定義接口或java內置實現的。server