觀察者模式簡介:
定義:定義對象間的一對多的依賴關係,當一個對象的狀態改變時,所有依賴於它的對象都得到通知並被自動更新。
原理:由四部分組成抽象目標類,具體目標類,抽象觀察者類,具體觀察者類
Subject .java</p><p>public interface Subject{<br /> void attach(Observer observer);//添加觀察者<br /> void detach(Observer observer);//刪除觀察者<br /> void inform();//通知所有觀察者<br />}<br />public interface Subject{<br /> void attach(Observer observer);//添加觀察者<br /> void detach(Observer observer);//刪除觀察者<br /> void inform();//通知所有觀察者<br />}</p><p>ConcreteSubject .java</p><p>public class ConcereteSubject implements Subject.java{<br /> public void attach(Observer observer){<br /> observersVector.addElement(observer);<br /> }<br /> public void attach(Observer observer){<br /> observersVector.removeElement(observer);<br /> }<br /> public void inform(){<br /> //對observersVector中的所有元素調用其update方法<br /> }<br />}<br />public class ConcereteSubject implements Subject.java{<br /> public void attach(Observer observer){<br /> observersVector.addElement(observer);<br /> }<br /> public void attach(Observer observer){<br /> observersVector.removeElement(observer);<br /> }<br /> public void inform(){<br /> //對observersVector中的所有元素調用其update方法<br /> }<br />}</p><p>Observer.java</p><p>public interface Observer{<br /> void update();//更新觀察者<br />}<br />public interface Observer{<br /> void update();//更新觀察者<br />}</p><p>ConcreteObserver.java</p><p>public class ConcreteObserver implements Observer{<br /> public void update(){<br /> }<br />}<br />public class ConcreteObserver implements Observer{<br /> public void update(){<br /> }<br />}</p><p>使用java.util.Observer介面和java.util.Observable類實現觀察者模式:</p><p>觀察者實現Observer介面,並重寫其中的update方法,供被觀察者狀態改變時調用。</p><p>被觀察者繼承Observable類,在Observable類中有增加,刪除觀察者類的方法,還有通知所有觀察者都update的方法。狀態改變時,先setChanged,再notifyObservers。</p><p>Observer介面源碼:</p><p>package java.util;<br />public interface Observer<br />{<br />/**<br />* 當被觀察的對象發生變化時,這個方法會被調用。<br />*/<br />void update(Observable o, Object arg);<br />}<br />package java.util;<br />public interface Observer<br />{<br />/**<br />* 當被觀察的對象發生變化時,這個方法會被調用。<br />*/<br />void update(Observable o, Object arg);<br />}</p><p>Observable類源碼:</p><p>package java.util;<br />public class Observable<br />{<br />private boolean changed = false;<br />private Vector obs;<br />/** 用0個觀察者構造一個被觀察者。**/<br />public Observable()<br />{<br />obs = new Vector();<br />}<br />/**<br />* 將一個觀察者加到觀察者列表上面。<br />*/<br />public synchronized void addObserver(Observer o)<br />{<br />if (!obs.contains(o))<br />{<br />obs.addElement(o);<br />}<br />}<br />/**<br />* 將一個觀察者對象從觀察者列表上刪除。<br />*/<br />public synchronized void deleteObserver(Observer o)<br />{<br />obs.removeElement(o);<br />}<br />/**<br />* 相當於 notifyObservers(null)<br />*/<br />public void notifyObservers()<br />{<br />notifyObservers(null);<br />}<br />/**<br />* 如果本對象有變化(那時hasChanged 方法會返回true)<br />* 調用本方法通知所有登記在案的觀察者,即調用它們的update()方法,<br />* 傳入this和arg作為參量。<br />*/<br />public void notifyObservers(Object arg)<br />{<br />/**<br />* 臨時存放當前的觀察者的狀態。參見備忘錄模式。<br />*/<br />Object[] arrLocal;<br />synchronized (this)<br />{<br />if (!changed) return;<br />arrLocal = obs.toArray();<br />clearChanged();<br />}<br />for (int i = arrLocal.length-1; i>=0; i--)<br />((Observer)arrLocal[i]).update(this, arg);<br />}<br />/**<br />* 將觀察者列表清空<br />*/<br />public synchronized void deleteObservers()<br />{<br />obs.removeAllElements();<br />}<br />/**<br />* 將“已變化”設為true<br />*/<br />protected synchronized void setChanged()<br />{<br />changed = true;<br />}<br />/**<br />* 將“已變化”重設為false<br />*/<br />protected synchronized void clearChanged()<br />{<br />changed = false;<br />}<br />/**<br />* 探測本對象是否已變化<br />*/<br />public synchronized boolean hasChanged()<br />{<br />return changed;<br />}<br />/**<br />* 返還被觀察對象(即此對象)的觀察者總數。<br />*/<br />public synchronized int countObservers()<br />{<br />return obs.size();<br />}<br />}<br />使用時機:</p><p>1. 當一個對象的改變需要同時改變其他對象,而且它不知道具體有多少對象有待改變時, 應該考慮使用觀察者模式;</p><p>2. 一個抽象模型有兩個方面,其中一個方面依賴於另一方面, 這時用觀察者模式可以將這兩者封閉在獨立的對象中使它們各自獨立地改變和複用;</p><p>3. 觀察者模式所做的工作其實就是在解除耦合。讓耦合的雙方都依賴於抽象,而不是依賴於具體,從而使得各自的變化都不會影響另一邊的變化。</p><p>
本篇文章來源於:http://edu.codepub.com/2009/1102/17225_2.php