簡單地說,觀察者模式定義了一個一對多的依賴關係,讓一個或多個觀察者對象監察一個主題對象。這樣一個主題對象在狀態上的變化可以通知全部的依賴於此對象的那些觀察者對象,使這些觀察者對象可以自動更新。類圖以下:java
抽象主題(Subject)角色:主題角色把全部觀察者對象的引用保存在一個列表裏。每一個主題均可以有任何數量的觀察者。主題提供了能夠添加或刪除觀察者對象的接口。抽象主題角色又叫作抽象被觀察者角色,能夠用一個抽象類或者一個接口實現。ide
抽象觀察者(Observer)角色:爲全部的具體觀察者定義一個接口,在獲得通知時更新本身;抽象觀察者角色能夠用一個抽象類或者一個接口實現;測試
具體主題(ConcreteSubject)角色:保存對具體觀察者對象有用的內部狀態;在這種內部狀態改變時給其觀察者發出一個通知;具體主題角色又叫做具體被觀察者角色,它一般是抽象主題的一個具體子類實現。this
具體觀察者(ConcreteObserver)角色:保存一個指向具體主題對象的引用和一個與主題的狀態相符的狀態。具體觀察者角色實現抽象觀察者角色所要求的更新本身的接口,以便使自己的狀態與主題的狀態自恰。具體觀察者角色一般是抽象觀察者的一個具體子類實現。spa
示例代碼:code
抽象主題:
server
package a1; /** * 抽象主題 */ public interface Subject { void attach(Observer observer); void detach(Observer observer); void notifyObservers(); }
抽象觀察者:對象
package a1; /** * 抽象觀察者 */ public interface Observer { void update(); }
具體主題:接口
package a1; import java.util.LinkedList; import java.util.List; /** * 具體主題 */ public class ConcreteSubject implements Subject { private List<Observer> li = new LinkedList<Observer>(); @Override public void attach(Observer observer) { li.add(observer); } @Override public void detach(Observer observer) { li.remove(observer); } @Override public void notifyObservers() { if(li.size() > 0){ for(Observer o : li){ o.update(); } } } }
具體觀察者:事件
package a1; /** * 具體觀察者 */ public class ConcreteObserver implements Observer { @Override public void update() { System.out.println(this.getClass().getName()); } }
測試:
package a1; public class Test { public static void main(String[] args) { Subject sub = new ConcreteSubject(); Observer ob = new ConcreteObserver(); sub.attach(ob); sub.notifyObservers(); } }
Java語言提供對觀察者模式的支持
由於從AWT1.1開始視窗系統的事件模型採用觀察者模式,所以觀察者模式在Java語言裏的地位較爲重要。正由於這個緣由,Java語言給出了它本身對觀察者模式的支持。所以,建議讀者在本身的系統中應用觀察者模式時,不妨利用Java語言所提供的支持。在Java語言的java.util庫裏面,提供了一個Observable類以及一個Observer接口,構成Java語言對觀察者模式的支持(具體查看API文檔)。