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

Java設計模式11:觀察者模式

一、什麼是觀察者模式

在閻巨集博士的《JAVA與模式》一書中開頭是這樣描述觀察者(Observer)模式的:

  觀察者模式是物件的行為模式,又叫釋出-訂閱(Publish/Subscribe)模式、模型-檢視(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。

  觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件。這個主題物件在狀態上發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己。

二、觀察者模式所涉及的角色

抽象被觀察者角色:也就是一個抽象主題,它把所有對觀察者物件的引用儲存在一個集合中,每個主題都可以有任意數量的觀察者。抽象主題提供一個介面,可以增加和刪除觀察者角色。一般用一個抽象類和介面來實現。

抽象觀察者角色:為所有的具體觀察者定義一個介面,在得到主題通知時更新自己。

具體被觀察者角色:也就是一個具體的主題,在集體主題的內部狀態改變時,所有登記過的觀察者發出通知。

具體觀察者角色:實現抽象觀察者角色所需要的更新介面,一邊使本身的狀態與製圖的狀態相協調。

三、程式碼示例:

在上程式碼之前,我們先假設下這樣的使用場景:有一個通知服務(比如微信公眾號),向用戶推送訊息,使用者關注公眾號就可以收到推送訊息,取消關注就收不到推送訊息。

 

先建立抽象觀察者介面和抽象被觀察者介面

/**
 * <pre>
 *    @author : orange
 *    @e-mail : 
[email protected]
* @time : 2018/10/18 10:40 * @desc : 抽象觀察者介面 * @version: 1.0 * </pre> */ public interface Observer { public void update(String message); }

 

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/18 10:39
 *    @desc   : 抽象被觀察者介面
 *    @version: 1.0
 * </pre>
 */
public interface Observerable {

    public void addObserver(Observer observer);
    public void removeObserver(Observer observer);
    public void notifyObserver();
}

被觀察者介面實現類:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/18 10:43
 *    @desc   : 具體的被觀察者實現
 *    @version: 1.0
 * </pre>
 */
public class ObserverableImpl implements Observerable{

    private List<Observer> list = new ArrayList<>();

    private String message;


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

    @Override
    public void removeObserver(Observer observer) {
        list.remove(observer);
    }

    @Override
    public void notifyObserver() {
        for (int i = 0; i < list.size(); i++) {
            Observer observer = list.get(i);
            observer.update(message);
        }

    }

    public void pushMessage(String message){
        this.message = message;

        //通知所有觀察者,推送訊息
        notifyObserver();

    }

}

具體的觀察者:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/18 11:00
 *    @desc   :
 *    @version: 1.0
 * </pre>
 */
public class User implements Observer {

    private String mrssage;
    private String name;

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


    @Override
    public void update(String message) {
        this.mrssage = message;
        System.out.println(name + "收到推送訊息:" + message);
    }
}

最後客戶端測試:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/18 11:03
 *    @desc   : 客戶端測試
 *    @version: 1.0
 * </pre>
 */
public class Client {
    public static void main(String[] args){

        ObserverableImpl observerable = new ObserverableImpl();
        Observer observer1 = new User("張飛");
        Observer observer2 = new User("關羽");
        Observer observer3 = new User("劉備");

        observerable.addObserver(observer1);
        observerable.addObserver(observer2);
        observerable.addObserver(observer3);

        observerable.pushMessage("通知來了");

    }
}

 

四、總結:

觀察者模式的好處:

觀察者模式提供了一種物件設計,讓主題和觀察者之間耦合度降得很低,為什麼呢?關於觀察者的一切,主題只知道觀察者實現了Observer介面,並不需要觀察者具體的類是誰,做了什麼或者其他細節.

這樣的話,由於鬆耦合,改變主題或者觀察者其中一方,並不會影響另一方,只要他們之間的介面仍被遵守,就可以自由地改變它.

降低物件之間的耦合度,也是面設物件設計的一個很重要的原則.