觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態上發生變化時,會通知全部觀察者對象,讓他們可以自動更新本身。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內置觀察者模式框架提供了類Observable
與接口Observer
。 類Observable
對應抽象主題角色,內部維護Vector
集合來存儲具體觀察者角色接口Observer
對應的抽象觀察者角色cdn
開發者要作的事情:
具體主題角色
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);
}
}
複製代碼