Android設計模式:觀察者模式

  • 定義對象間的一種一個對多的依賴關系,當一個對象的狀態(tài)發(fā)送改變時,所以依賴于它的對象都得到通知并被自動更新。

一、觀察者模式

  • 抽象主題(Subject):它把所有觀察者對象的引用保存到一個集合中,每個主題都可以有任何數(shù)量的觀察者。抽象主題提供一個接口,可以注冊和移除觀察者。
  • 具體主題(ConcreteSubject):將有關狀態(tài)存入具體觀察者對象;在具體主題內部狀態(tài)改變時,給所有登記過的觀察者發(fā)出通知。
  • 抽象觀察者(Observer):為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。
  • 具體觀察者(ConcreteObserver):實現(xiàn)抽象觀察者提供的更新接口,以便本身的狀態(tài)能夠及時更新。

(1)代碼實現(xiàn)

  • 抽象觀察者:定義一個接到通知的更新方法
public interface Observer {
    void update(Observable o, Object arg);//更新方法
}
  • 具體觀察者
public class ConcreteObserverA implements Observer {
    private String name;

    public ConcreteObserverA(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("觀察者" + name + "---->" + arg.toString());
    }
}

public class ConcreteObserverB implements Observer {
    private String name;

    public ConcreteObserverB(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("觀察者" + name + "---->" + arg.toString());
    }
}
  • 抽象主題:抽象被觀察者
public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    public Observable() {
        obs = new Vector<>();
    }

    //添加
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    //刪除
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    //更新
    public void notifyObservers() {
        notifyObservers(null);
    }

    public void notifyObservers(Object arg) {
        Object[] arrLocal;
        synchronized (this) {
            if (!hasChanged())
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    //刪除全部
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    protected synchronized void setChanged() {
        changed = true;
    }

    protected synchronized void clearChanged() {
        changed = false;
    }

    public synchronized boolean hasChanged() {
        return changed;
    }

    //觀察者數(shù)量
    public synchronized int countObservers() {
        return obs.size();
    }
}

  • 具體主題:具體被觀察者
public class ConcreteSubject extends Observable {
    private static ConcreteSubject concreteSubject;
    private List<Observer> list = new ArrayList<>();

    public static ConcreteSubject getInstance() {
        if (null == concreteSubject) {
            synchronized (ConcreteSubject .class) {
                if (null == concreteSubject) {
                    concreteSubject = new ConcreteSubject();
                }
            }
        }
        return concreteSubject;
    }

    @Override
    public synchronized void addObserver(Observer o) {
        list.add(o);
    }

    @Override
    public synchronized void deleteObserver(Observer o) {
        if (list.contains(o)) {
            list.remove(o);
        }
    }

    @Override
    public synchronized void deleteObservers() {
        list.clear();
    }

    @Override
    public void notifyObservers(Object arg) {
        for (Observer observer : list) {
            observer.update(null, arg);
        }
    }
}
  • 調用實現(xiàn)
        ConcreteObserverA concreteObserverA = new ConcreteObserverA("小張");
        ConcreteObserverB concreteObserverB = new ConcreteObserverB("小李");
        ConcreteSubject.getInstance().addObserver(concreteSubjectA);
        ConcreteSubject.getInstance().addObserver(concreteSubjectB);
        ConcreteSubject.getInstance().notifyObservers("觀察者請刷新信息");
  • 解除觀察者與主題之間的耦合。讓耦合的雙方都依賴于抽象,而不是依賴具體。從而使得各自的變化都不會影響另一邊的變化。
  • 易于擴展,對同一主題新增觀察者時無需修改原有代碼。
  • 依賴關系并未完全解除,抽象主題仍然依賴抽象觀察者。
  • 使用觀察者模式時需要考慮一下開發(fā)效率和運行效率的問題,程序中包括一個被觀察者、多個觀察者,開發(fā)、調試等內容會比較復雜,而且在Java中消息的通知一般是順序執(zhí)行,那么一個觀察者卡頓,會影響整體的執(zhí)行效率,在這種情況下,一般會采用異步實現(xiàn)。
  • 可能會引起多余的數(shù)據(jù)通知。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容