1. 程式人生 > 程式設計 >觀察者模式

觀察者模式

觀察者模式

觀察者模式(有時又被稱為釋出(publish )-訂閱(Subscribe)模式、模型-檢視(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟體設計模式的一種。在此種模式中,==一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知==。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。

優點

  • 省去了反覆檢索狀態的資源消耗(輪詢)
  • 得到更快的反應速度

缺點

  1. 如果一個被觀察者物件有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
  2. 如果在觀察者和觀察目標之間有迴圈依賴的話,觀察目標會觸發它們之間進行迴圈呼叫,可能導致系統崩潰。
  3. 觀察者模式沒有相應的機制讓觀察者知道所觀察的目標物件是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。

適用場景

季度分享差不多落幕,大家滿心期待大波的審批結果,沒人心裡無時無刻不想去大波那裡問一下結果如何,但是這樣大波心裡叫苦,每時每刻都有人來騷擾,不勝其煩,所以,觀察者模式出場

類圖如下

觀察者模式

例項程式碼

package com.jack.idea.test.designmode;


import java.util.ArrayList;
import java.util.List;

/**
 * 觀察者模式
 *
 * @author ljs.song
 * @date 2018-01-02 10:40
 */
public class ObserverClient {

    public static void main(String[] args) {
        //大boss大波出場
        DaboSubject daboSubject = new DaboSubject();
        //小杰向大boss表明想第一時間知道結果
        XiaoJieObserver xiaoJieObserver = new XiaoJieObserver();
        daboSubject.registerObserver(xiaoJieObserver);

        //小臣也想知道結果
        XiaoChenObserver xiaoChenObserver = new XiaoChenObserver();
        daboSubject.registerObserver(xiaoChenObserver);

        //小龍表示我也想知道
        XiaoLongObserver xiaoLongObserver = new XiaoLongObserver();
        daboSubject.registerObserver(xiaoLongObserver);

        //大波進行一次初步評審變動
        daboSubject.notifyAllObserver("大家好我初步做了評審,請檢視是否有疑問");
        System.out.println("--------------------------");
        //小龍覺得有疑問,告訴了大波,大波重新修改了小龍的評審結果
        daboSubject.notifyObserver(2,"我給你改了,再看下有沒有問題");
    }
}

/**
 * 被觀察者,主題
 */
abstract class Subject{

    protected List<Observer> observers = new ArrayList<>();

    void registerObserver(Observer observer){
        if(observer != null && !observers.contains(observer)){
            observers.add(observer);
        }
    }

    void removeObserver(Observer observer){
        if(observer != null && observers.contains(observer)){
            observers.remove(observer);
        }
    }

    /**
     * 通知全部觀察者
     */
    abstract void notifyAllObserver(String messages);

    /**
     * 通知指定觀察者
     * @param i
     * @param message
     */
    abstract void notifyObserver(int i,String message);
}

/**
 * 觀察者
 */
interface Observer{

    void update(String message);
}

/**
 * 大波,真正的被觀察者
 */
class DaboSubject extends Subject {


    /**
     * 狀態變化後通知各個觀察者
     */
    @Override
    public void notifyAllObserver(String message) {
        for (Observer observer1 : this.observers) {
            observer1.update(message);
        }
    }

    @Override
    void notifyObserver(int i,String message) {
        observers.get(i).update(message);
    }
}

/**
 * 小杰接受被觀察者的資訊
 */
class XiaoJieObserver implements Observer{

    @Override
    public void update(String message) {
        System.out.println("小杰收到通知:" + message);
    }
}

/**
 * 小臣等待被觀察者的資訊
 */
class XiaoChenObserver implements Observer{

    @Override
    public void update(String message) {
        System.out.println("小辰收到通知:" + message);
    }
}

/**
 * 小龍等待資訊公佈
 */
class XiaoLongObserver implements Observer{

    @Override
    public void update(String message) {
        System.out.println("小龍收到通知:" + message);
    }
}複製程式碼

轉載請註明出處 阿布的夏天