基於觀察者模式獲取天氣信息的實例
觀察者模式定義:
觀察者模式是軟件設計模式的一種,也被稱為模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式。觀察者模式定義了一個一對多的依賴關系,讓一個或多個觀察者對象監察一個主題對象,這樣一個主題對象在狀態上的變化能夠通知所有的依賴於此對象的那些觀察者對象,使這些觀察者對象能夠自動更新。
觀察者模式結構:
觀察者模式有如下角色:
抽象(Subject)主題角色:主題角色把所有的觀察者對象的引用保存在一個列表裏;每個主題都可以有任何數量的觀察者。主題提供一個接口可以加上或撤銷觀察者對象;主題角色又叫做抽象被觀察者(Observable)角色;
抽象觀察者(Observer)角色:
具體主題(ConcreteSubject)角色:保存對具體觀察者對象有用的內部狀態;在這種內部狀態改變時給其觀察者發出一個通知;具體主題角色又叫作具體被觀察者角色;
具體觀察者(ConcreteObserver)角色:保存一個指向具體主題對象的引用;和一個與主題的狀態相符的狀態。具體觀察者角色實現抽象觀察者角色所要求的更新自己的接口,以便使本身的狀態與主題的狀態自恰。
具體實例:
觀察者接口:
/** *觀察者接口 */ public interface Observer { void update(Subject subject); }
具體觀察者:
public class ConcretObserver implements Observer{ private String observerName; private String observerState; public void setObserverName(String observerName) { this.observerName = observerName; } @Override public void update(Subject subject) { observerState= ((ConcreteSubject)subject).getWeatherContent(); System.out.println(observerName + " 收到 "+observerState); } }
抽象被觀察者:
public class Subject { private ArrayList<Observer> observers = new ArrayList<Observer>(); public void attach(Observer observer){ observers.add(observer); } public void detach(Observer observer){ observers.remove(observer); } protected void notifyObservers(){ for (Observer observer:observers){ observer.update(this); } } }
具體被觀察者:
public class ConcreteSubject extends Subject { private String weatherContent; public String getWeatherContent() { return weatherContent; } public void setWeatherContent(String weatherContent) { this.weatherContent = weatherContent; this.notifyObservers(); } }
客戶端調用:
public class Client { public static void main(String[] args){ ConcreteSubject subject = new ConcreteSubject(); ConcretObserver o1 = new ConcretObserver(); o1.setObserverName("vivi "); subject.attach(o1); ConcretObserver o2 = new ConcretObserver(); o2.setObserverName("jimi "); subject.attach(o2); subject.setWeatherContent("晴天 ,溫度28 微風 "); } }
觀察者模式的優缺點:
優點:
(1) 觀察者模式可以實現表示層和數據邏輯層的分離,定義了穩定的消息更新傳遞機制,並抽象了更新接口,使得可以有各種各樣不同的表示層充當具體觀察者角色。
(2) 觀察者模式在觀察目標和觀察者之間建立一個抽象的耦合。觀察目標只需要維持一個抽象觀察者的集合,無須了解其具體觀察者。由於觀察目標和觀察者沒有緊密地耦合在一起,因此它們可以屬於不同的抽象化層次。
(3) 觀察者模式支持廣播通信,觀察目標會向所有已註冊的觀察者對象發送通知,簡化了一對多系統設計的難度。
(4) 觀察者模式滿足“開閉原則”的要求,增加新的具體觀察者無須修改原有系統代碼,在具體觀察者與觀察目標之間不存在關聯關系的情況下,增加新的觀察目標也很方便。
缺點:
(1) 如果一個觀察目標對象有很多直接和間接觀察者,將所有的觀察者都通知到會花費很多時間。
(2) 如果在觀察者和觀察目標之間存在循環依賴,觀察目標會觸發它們之間進行循環調用,可能導致系統崩潰。
(3) 觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎麽發生變化的,而僅僅只是知道觀察目標發生了變化。
GitHub源碼:https://github.com/jingdq/ObserverPattern/tree/master/src/com/jing
基於觀察者模式獲取天氣信息的實例