直接崩潰了,看了好長時間才明白一點其中的意思,先初次記錄一下,等有更深層次的理解時再繼續編輯。
在《Head.First設計模式》中,對觀察者模式的解釋非常生動,理解起來也很容易,但是,真正自己寫一個實現為什麼怎麼就這麼難呢?哎……好吧,記錄一下主要的學習內容。
一、觀察者模式引入
首先,說一下這個被稱為皇后的觀察者模式:觀察者模式定義了一系列對象之間的一對多依賴關係;當一個對象改變狀態,其他依賴者都會收到通知並自動更新。其中,“一”指的是主題,“多”指的是觀察者。觀察者可以“註冊”後獲得“主題”改變時的及時通知。
如果還不是很好理解,我們繼續:比如有讀者樂樂、皮皮、大皮皮、破皮。出版社發放報紙,四位讀者可以訂閱。如果樂樂想訂閱,那麼,他會告訴出版商,我要訂閱報紙,之後,出版社一有新的報紙出來的時候,就會及時發放到樂樂手中。同理,皮皮想訂閱的話,也可以這樣。如果訂閱一段時間後,樂樂不想訂了,可以直接告訴出版商,我不訂閱了,這樣,之後的資訊更新就不會再通知給樂樂。 觀察者模式就是這樣一個過程,可以靈活的接受對象的“註冊”,也可以允許使用者物件“登出”。“註冊”的使用者可以及時得到主題對象的更新內容,而沒有訂閱的就不能得到。
下面是類圖:
二、觀察者模式設計舉例
實現功能:學校發布資訊,學生可以訂閱,老師可以訂閱,行政人員也可以訂閱。
思路:定義主題介面,觀察者介面,定義Notice 、學生、老師和行政人員類,定義測試類別。其中Notice類實現主題介面,老師、學生和行政人員實現觀察者介面。
實現過程:(注釋中有解釋)
1、定義主題介面
Code:
- public interface Subjects{
- //註冊訂閱使用者
- public void registerObservers(Observer o);
- //對使用者發送新的通知
- public void notifyObservers();
- //登出使用者
- public void removeObservers(Observer o);
- }
2、定義觀察者介面
Code:
- public interface Observer{
- //notice通過調用此方法實現向訂閱者發送資訊的功能
- public void givenotice(String s);
- }
3、定義Notice類
Code:
- import java.util.ArrayList;
- //實現主題介面
- public class Notice implements Subjects{
-
- private String ss = new String();
- private ArrayList observers;
- public Notice(){
- observers = new ArrayList();
- }
- //主題介面方法,登出訂閱使用者
- public void removeObservers(Observer o){
- int i = observers.indexOf(o);
- if (i>=0){
- observers.remove(i);
- }
- }
- //主題介面方法,添加訂閱的使用者
- public void registerObservers (Observer o){
- observers.add(o);
- }
- //主題介面方法,通過遍曆向訂閱者發送訊息
- public void notifyObservers(){
- for (int i=0; i<observers.size();i++){
- Observer observer = (Observer)observers.get(i);
- observer.givenotice(ss);
- }
- }
- //供測試用
- public void setContent(String ss){
- this.ss = ss;
- this.notifyObservers();
- }
- }
4、定義Student類
Code:
- public class Student implements Observer{
- //實現Observer的方法
- public void givenotice(String ss){
-
- System.out.println("學生:"+ss);
- }
- }
5、再定義一個Teacher類
Code:
- public class Teacher implements Observer{
-
- //實現observers中的givenotice()方法
- public void givenotice(String ss){
-
- System.out.println("老師:"+ss);
-
- }
- }
6、用Test類實現測試
Code:
- public class Test{
- //這是測試
- public static void main(String args[]){
- Notice n = new Notice();
- Student student = new Student();
- Teacher teacher = new Teacher();
- n.registerObservers(student);
- n.registerObservers(teacher);
-
- //因為沒有可以自動調用Notice中的方法的實現,所以,只好通過這個測試了
- n.setContent("ahaha");
- //登出student使用者
- n.removeObservers(student);
n.setContent("ahaha");
- }
- }
7、輸出結果
學生:ahaha
老師:ahaha
老師:ahaha(登出student後)