Java設計模式-觀察者模式

觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態上發生變化時,會通知全部觀察者對象,讓他們可以自動更新本身。java

組成部分

抽象主題角色

把全部觀察者對象的引用保存在一個集合中,每一個抽象主題角色均可以有任意數量的觀察者,抽象主題提供一個接口,能夠增長和刪除觀察者角色,通常用一個抽象類或接口來實現。編程

具體主題角色

在具體主題內部狀態改變時,給全部登記過的觀察者發出通知,具體主題角色一般用一個子類實現。bash

抽象觀察者角色

爲全部具體的觀察者定義一個接口,在獲得主題的通知時更新本身框架

具體觀察者角色

該角色實現抽象觀察者角色所要求的更新接口,以便使自己的狀態與主題的狀態相協調,若是須要,具體觀察者角色能夠保有一個指向具體主題角色的引用,一般用一個子類實現ide

代碼示例

抽象主題角色測試

public interface AbstractSubject {
    public void addObserver(AbstractObserver observer);
    public void removeObserver(AbstractObserver observer);
    public void notification();
}
複製代碼

具體主題角色ui

public class ConcreteSubject implements AbstractSubject {
    List<AbstractObserver> list = new ArrayList<AbstractObserver>();
    
    @Override
    public void addObserver(AbstractObserver observer) {
        list.add(observer);
    }

    @Override
    public void removeObserver(AbstractObserver observer) {
        list.remove(observer);
    }

    // 狀態改變了,全部觀察者更新本身的界面
    @Override
    public void notification() {
        for (AbstractObserver abstractObserver : list) {
            abstractObserver.update();
        }
    }

}
複製代碼

抽象觀察者角色spa

public interface AbstractObserver {
    public void update();
}
複製代碼

測試類code

class Client {
    public static void main(String[] args) {
        //生成一個主題角色
        AbstractSubject subject = new ConcreteSubject();
        //爲主題角色增長觀察者對象,這裏採用匿名內部類的方式,與AWT編程裏的安裝監聽器相似
        subject.addObserver(new AbstractObserver() {
            @Override
            public void update() {
                System.out.println("A同窗您的APP須要更新");
            }
        });
        subject.addObserver(new AbstractObserver() {
            @Override
            public void update() {
                System.out.println("B同窗您的APP須要更新");
            }
        });
        subject.addObserver(new AbstractObserver() {
            @Override
            public void update() {
                System.out.println("C同窗您的APP須要更新");
            }
        });
        subject.notification();
    }
}
複製代碼

Java內置的觀察者模式框架

java內置觀察者模式框架提供了類Observable接口Observer類Observable對應抽象主題角色,內部維護Vector集合來存儲具體觀察者角色接口Observer 對應的抽象觀察者角色cdn

開發者要作的事情:

  1. 寫一個類(具體主題角色)繼承Observable(抽象主題角色),只須要寫一個change方法便可 (該方法做用是通知已註冊的具體主題角色更新本身)
  2. 寫一個類(具體觀察者角色)實現Observer(抽象觀察者角色),只須要實現方法update(Observable o, Object arg)便可
  3. 寫一個測試類進行測試

代碼示例

具體主題角色

public class Watched extends Observable {
    //狀態改變的時候調用已註冊的觀察者的update方法,讓它們更新本身
    public void count(int number) {
        for (; number >= 0; number--) {
            try {
                Thread.sleep(1000);
                setChanged();
                notifyObservers(number);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
複製代碼

具體觀察者角色

public class Watcher implements Observer {
    //當主題角色事件觸發時,會調用全部已註冊的具體觀察者角色的update方法
    @Override
    public void update(Observable o, Object arg) {
        int number = (Integer) arg;
        System.out.println(number);
    }
}
複製代碼

測試類

public class Client {
    public static void main(String[] args) {
        //建立主題角色
        Watched watched = new Watched();
        //建立觀察者角色
        Observer watcher1 = new Watcher();
        Observer watcher2 = new Observer() {
            @Override
            public void update(Observable o, Object arg) {
                int number = (Integer) arg;
                if (0 == number) {
                    System.out.println("done");
                }
            }
        };
        watched.addObserver(watcher1);
        watched.addObserver(watcher2);
        watched.count(10);
    }
}
複製代碼

總結

  • 被觀察者要繼承Observable類
  • 被觀察者通知觀察者時,也就是調用notifyObservers方法時必定要先調用setChanged()方法,該方法做用是將對象裏面的changed這個boolean變量設爲true,由於notifyObservers要首先檢查該變量是否爲true,若是爲false就不執行而直接返回了。
  • Observable類的兩個重載的notifyObservers方法,帶參數的那個方法裏面的參數就是Observer接口中的update方法中的第二個參數。

相關文章
相關標籤/搜索