/注:場景和例子引用github上的設計模式。傳送門:https://github.com/iluwatar/java-design-patterns/tree/master/observerjava
一個天氣預報系統,凡是訂閱了改天氣預報的,當天氣發生改變的時候就把通知發送給全部訂閱該天氣預報的人。如獸人族(Orcs)和霍比特人(Hobitts)訂閱了該天氣預報系統,當天氣從晴變成雨天的時候,獸人族和霍比特人就收到了天氣變成雨天的通知。 若是還有其餘訂閱了該天氣預報的如人族(Terran),只須要在WeatherObserver中加入該人族(Terran)訂閱者,這樣當天氣發生改變的時候,人族也會收到天氣通知。git
定義對象間的一對多關係,當一個對象發生狀態更改時,會自動通知並更新全部依賴者。github
訂閱天氣預報系統的便是觀察者(如Orcs、Hobitts),把這些訂閱天氣預報的人抽象成接口(WeatherObserver),全部訂閱該天氣預報的人都得實現這個接口才行。另外在天氣類(Weather)中也得開放一個接口讓他們訂閱,如使用List<Subscriber> observers 和寫一個方法 addObserver(WeatherObserver obs)來讓他們訂閱,一旦天氣發生變化就通知全部訂閱該天氣的方法 notifyAllObserver()。設計模式
talk is cheap,show me the code............................................................................................................................................................................................................................................................(分割線)數據結構
先定義天氣類型(WeatherType.java),定義爲枚舉類型(sunny,rainny,windy,clod)ide
public enum WeatherType {
SUNNY,WINDY,CLOD,RAINY;
@Override
public String toString(){
return this.name().toLowerCase();
}
}
再將訂閱者抽象成一個接口(WeatherObserver.java),全部訂閱天氣預報系統的必須實現這個接口。測試
public interface WeatherObserver { public void Upadate(WeatherType currentWeather); }
天氣類(Weather)負責定義數據結構來接收訂閱者和通知更新訂閱者天氣變化。使用List<WeatherObserver>來接收訂閱者,定義方法addObserver來接收新的訂閱者和notifyAllObsever方法來更新訂閱者天氣狀態。this
import java.util.ArrayList; import java.util.List; public class Weather { private WeatherType currentWeather; private List<WeatherObserver> observers; public Weather(){ observers=new ArrayList<>(); currentWeather=WeatherType.SUNNY; } public void addObservers(WeatherObserver observer){ observers.add(observer); } public void removeObservers(WeatherObserver observer){ observers.remove(observer); } public void timePasses(){ WeatherType[] enumValues=WeatherType.values(); /* for(WeatherType type:enumValues){ System.out.println(type); }*/
//改變天氣,讓天氣的enum類型日後推一個
currentWeather=enumValues[(currentWeather.ordinal() + 1) % enumValues.length]; System.out.println("The weather change to "+currentWeather); notifyAllObserver(); } public void notifyAllObserver(){ for(WeatherObserver obs: observers){ obs.Upadate(currentWeather); } } }
添加兩個訂閱天氣預報的「人」,一個獸族(Orcs.java)一個霍比特人(Hobitts.java)。 如上面所說,要訂閱該天氣預報必須實現WeatherOberver接口。spa
public class Orcs implements WeatherObserver{ @Override public void Upadate(WeatherType currentWeather) { switch(currentWeather){ case CLOD: System.out.println("The orcs are freezing cold"); break; case SUNNY: System.out.println("The sun hurts the orcs' eyes."); break; case RAINY: System.out.println("The orcs are dripping wet."); break; case WINDY: System.out.println("The orc smell almost vanishes in the wind."); default: break; } } public class Hobbits implements WeatherObserver{ @Override public void Upadate(WeatherType currentWeather) { switch(currentWeather){ case CLOD: System.out.println("The Hobbits are freezing cold"); break; case SUNNY: System.out.println("The sun hurts the Hobbits' eyes."); break; case RAINY: System.out.println("The Hobbits are dripping wet."); break; case WINDY: System.out.println("The Hobbits smell almost vanishes in the wind."); default: break; } } }
寫一個主類來測試一下改功能(App.java)設計
public class APP { public static void main(String[] args){ Weather weather=new Weather(); weather.addObservers(new Orcs()); weather.addObservers(new Hobbits()); //weather.addObservers(new Terran()); weather.timePasses(); //weather.timePasses();
} }
輸出:(即天氣從Sunny變成Windy的時候,訂閱該天氣的Orcs和Hobitts都收到了天氣改變的通知)
The weather change to windy
The orc smell almost vanishes in the wind.
The Hobbits smell almost vanishes in the wind.