《java與模式》-3 觀察者模式

簡介:
觀察者模式又叫:發佈-訂閱模式、模型-視圖模式、源-監聽模式或從屬模式。
定義了一種一對多的依賴關係,讓多個觀察者同時監聽同一個主題對象,這個主題對象在狀態上發生變化時,會通知所有的觀察者,使他們能夠自動更新自己

角色

  • 抽象主題:Observable類,註冊、保存、刪除觀察者,通知觀察者
  • 抽象觀察者:Observer接口,只有update方法
  • 具體主題角色:繼承Observable,在狀態改變時調用父類方法通知觀察者
  • 具體觀察者角色:實現Observer的update方法

具體主題角色(被觀察者)

package observer2.my;
import java.util.Observable;
/**
 - 被觀察者
 */
public class MyObservable extends Observable {
    public void change(String str){
        // 帶參數
        notifyHandlers();
        // 不帶參數
        notifyHandlers(str);
    }
    /**
     * 通知所有觀察者(處理者)
     */
    public void notifyHandlers() {
        // 如果有改變,後面才能執行 setChanged -->true
        setChanged();
        notifyObservers();
    }
    /**
     * 通知所有觀察者(處理者)
     */
    public void notifyHandlers(Object params) {
        setChanged();
        notifyObservers(params);
    }
}

觀察者

package observer2.my;
import java.util.Observable;
import java.util.Observer;
/**
 - 觀察者:
 -   當事件發生的時候 執行對應方法
 */
public class MyObserve implements Observer {
    public MyObserve(Observable observable) {
        // 直接註冊到 被觀察者的集合
        observable.addObserver(this);
    }
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("我收到了" + arg);
    }
}

測試

public class Test {
    public static void main(String[] args) {
        MyObservable myObservable = new MyObservable(); // 被觀察者
        MyObserve m1 = new MyObserve(); // 觀察者
        MyObserve m2 = new MyObserve(); // 觀察者
        MyObserve m3 = new MyObserve(); // 觀察者
        myObservable.change("哈哈哈");
    }
}

結果:
- 我收到了null
- 我收到了null
- 我收到了null
- 我收到了哈哈哈
- 我收到了哈哈哈
- 我收到了哈哈哈

觀察者基類

import java.util.Observable;
import java.util.Observer;
/**
 * 觀察者基類
 */
public abstract class BaseObserver implements Observer {
    /**
     * 同步執行
     */
    private boolean sync = true;
    @Override
    public void update(Observable observable, Object arg) {
        try {
            if (isSync()) {
                this.update((BaseObservable) observable, arg);
            } else {
                ObserverExecutor observerExecutor = new ObserverExecutor(this, (BaseObservable) observable, arg);
                new Thread(observerExecutor).start();
            }
        } catch (Exception e) {
            // logger.error("觀察事件執行異常:", e);
        }
    }
    public boolean isSync() {
        return sync;
    }
    public void setSync(boolean sync) {
        this.sync = sync;
    }
    /**
     * 事件觸發
     *
     * @param observable
     * @param arg
     */
    protected abstract void update(BaseObservable observable, Object arg);
}

/**
 * 觀察者執行器
 */
class ObserverExecutor implements Runnable {
    /**
     * 觀察者
     */
    private BaseObserver observer;
    /**
     * 被觀察對象
     */
    private BaseObservable observableObject;
    /**
     * 執行參數
     */
    private Object arguments;

    public ObserverExecutor(BaseObserver observer, BaseObservable observableObject, Object arguments) {
        this.observer = observer;
        this.observableObject = observableObject;
        this.arguments = arguments;
    }
    @Override
    public void run() {
        observer.update(observableObject, arguments);
    }
}

消費者(被觀察者)基類

import java.util.Observable;
/**
 * 消費者(被觀察者)基類
 */
public abstract class BaseObservable extends Observable {
    /**
     * 通知所有觀察者(處理者)
     */
    public void notifyHandlers() {
        setChanged();
        notifyObservers();
    }
    /**
     * 通知所有觀察者(處理者)
     */
    public void notifyHandlers(Object params) {
        setChanged();
        notifyObservers(params);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章