觀察者模式-Observer 當一個對象變化時,其它依賴該對象的對象都會收到通知, 並且會隨著變化!對象之間是一種一對多的關係。 換一種表達方式: 有很多觀察者們依賴於(觀察)同一個對象(主題), 當這個被依賴的對象(主題)變化時, 觀察者們也會隨之變化. 本文中的例子如下: 有一個進度生成器, 用 ...
觀察者模式-Observer
當一個對象變化時,其它依賴該對象的對象都會收到通知, 並且會隨著變化!對象之間是一種一對多的關係。
換一種表達方式: 有很多觀察者們依賴於(觀察)同一個對象(主題), 當這個被依賴的對象(主題)變化時, 觀察者們也會隨之變化.
本文中的例子如下: 有一個進度生成器, 用來模擬進度條的數值. 當進度數值更新後, 就會通知進度欄更新值. 也就是進度欄是觀察者, 隨時間在變的進度值是主題內容.
Observer介面
這是觀察者的統一定義. 主題被修改時, 通過調用update()方法來通知觀察者更新.
/** * 觀察者介面-觀察者的統一定義 */ public interface Observer { /** * Observer(觀察者)會被數值生成器通知, 來更新自己的狀態 */ void update(ProgressBar generator); }
DigitObserver類
數字進度類. 這是其中一種觀察者的實現, 也是一種具體的進度條.
/** * 將進度以數字形式展現出來 */ public class DigitObserver implements Observer { /** * Observer(觀察者)會被數值生成器通知, 來更新自己的狀態 */ @Override public void update(ProgressBar generator) { System.out.println("數字版進度條:" + generator.getNumber() + "%"); } }
GraphObserver類
圖形進度條, 這是其中一種觀察者的實現, 也就是一種具體的進度條.
/** * 將進度條以進度欄形式展現出來 */ public class GraphObserver implements Observer { /** * Observer(觀察者)會被數值生成器通知, 來更新自己的狀態 */ @Override public void update(ProgressBar generator) { System.out.print("圖形版進度條:"); int count = generator.getNumber(); for (int i = 0; i < count; i++) { System.out.print("*"); } System.out.println(""); } }
ProgressBar類
由本類來模擬 隨時間在漲的進度數值, 進度值變更後, 會通知進度條來更新自己的值.
/** * 生成數值的抽象類, 同時會保存觀察者們, 當數值生成的時候就會去通知所有觀察者們 */ public class ProgressBar { /** * 保存Observer們 */ private ArrayList<Observer> observers = new ArrayList<>(); /** * 當前數值 */ private int number; public int getNumber() { return number; } /** * 生成數值, 並通知給觀察者們 */ public void execute() { for (int i = 0; i <= 100; i += 10) { number = i; notifyObservers(); } } /** * 註冊Observer */ public void addObserver(Observer observer) { observers.add(observer); } /** * 向Observer發送通知 */ public void notifyObservers() { for (Observer o : observers) { o.update(this); } try { System.out.println(); Thread.sleep(400); } catch (InterruptedException e) { e.printStackTrace(); } } }
Main
public class Main { public static void main(String[] args) { // 進度值 ProgressValue progressValue = new ProgressValue(); // 圖形進度條, 和數值進度條 都訂閱了這個進度值 // 在進度值變化時, 這兩個觀察者就會更新自己的進度 progressValue.addObserver(new DigitObserver()); progressValue.addObserver(new GraphObserver()); // 進度值開始變動 progressValue.execute(); } }
運行結果如下: