1. 程式人生 > >Java中的設計模式 - 觀察者模式【又叫:釋出/訂閱模式】

Java中的設計模式 - 觀察者模式【又叫:釋出/訂閱模式】

文章目錄

Java中的設計模式 - 觀察者模式【又叫:釋出/訂閱模式】


1、觀察者模式是為了解決什麼問題

當我們在定義物件間的一種一對多的依賴關係,一個物件的狀態發生改變時,所有依賴於它的物件都會得到通知並被自動更新。

一個物件狀態改變給其他物件通知的問題,而且要考慮到易用和低耦合,保證高度的協作。所以使用觀察者模式

2、核心邏輯

在抽象類中有一個註冊觀察者的List 物件

3、優點

1、觀察者與被觀察者是抽象耦合的
2、存在觸發機制

4、缺點

1、如果某個被觀察物件,擁有很多的觀察者,則全部通知到會花費較多的時間
2、觀察者與被觀察者之間有可能存在迴圈依賴,導致系統宕機
3、觀察者對於被觀察者來說,是一個相對的黑箱,觀察者只知道結果是這樣,但是並不知道究竟是怎麼變成這樣的。

5、應用場景

1、釋出/訂閱
2、一個物件的狀態變更,會影響到與他關聯的物件
3、鏈式傳遞,一個物件的變更,會影響到與他關聯的物件,而這個狀態導致的關聯變更,又會影響到關聯物件的關聯物件,那麼可以設計一個鏈式觀察模式來傳遞變更

6、構建觀察者抽象類,抽離觀察者屬性
public abstract class Observer {
    protected Subject subject;
    public abstract void whileUpdate();
}

7、構建被觀察者,主題
@Getter
public class Subject {


    private List<Observer> observers = Lists.newArrayList();

    private Object data;

    public void whileDataUpdated(Object data) {
        this.data = data;
        notifyAllObserbers();
    }


    /**
     * 新增一個觀察者
     */
    public void newObserver(Observer observer) {
        observers.add(observer);
    }

    /**
     * 通知所以的觀察者
     */
    public void notifyAllObserbers() {
        observers.forEach(Observer::whileUpdate);
    }
}
8、建立3個觀察者 A B C
public class ObserverA extends Observer {



    public ObserverA(Subject subject) {
        this.subject = subject;
        this.subject.newObserver(this);
    }

    @Override
    public void whileUpdate() {
        System.out.println("我是A觀察者,我監聽到變化:" + subject.getData().toString());
    }
}




public class ObserverB extends Observer {


    public ObserverB(Subject subject) {
        this.subject = subject;
        this.subject.newObserver(this);
    }


    @Override
    public void whileUpdate() {
        System.out.println("我是B觀察者,我監聽到變化:" + subject.getData().toString());
    }
}


public class ObserverC extends Observer {


    public ObserverC(Subject subject) {
        this.subject = subject;
        this.subject.newObserver(this);
    }


    @Override
    public void whileUpdate() {
        System.out.println("我是C觀察者,我監聽到變化:" + subject.getData().toString());
    }
}

9、測試
public class Main {


    public static void main(String[] args) {
        Subject subject = new Subject();
        new ObserverA(subject);
        new ObserverB(subject);
        new ObserverC(subject);

        subject.whileDataUpdated("我註冊了一張銀行卡");
        subject.whileDataUpdated("我登出了一張銀行卡");

    }
}
10、輸出
我是A觀察者,我監聽到變化:我註冊了一張銀行卡
我是B觀察者,我監聽到變化:我註冊了一張銀行卡
我是C觀察者,我監聽到變化:我註冊了一張銀行卡
我是A觀察者,我監聽到變化:我登出了一張銀行卡
我是B觀察者,我監聽到變化:我登出了一張銀行卡
我是C觀察者,我監聽到變化:我登出了一張銀行卡