揭開觀察者模式的面紗

定義

觀察者模式是這樣定義的:在對象之間存在一對多的依賴關係,當主對象的狀態發生改變的時候,依賴它的全部從對象都能接收到改變的信息並作出相應的處理。好比老師和學生,微信公衆號和訂閱的用戶,消息隊列的生產者和消費者。觀察者模式的實質就是發佈訂閱模式,發佈者發佈消息,訂閱者獲取消息,訂閱了就能收到消息,沒訂閱就收不到消息。bash

UML

觀察者模式有四個角色:
一、抽象被觀察者:也就是一個抽象的主題,它將全部觀察者放到一個集合(隊列)中,這個主題定義了添加觀察者、一處觀察者,以及通知觀察者等方法。
二、抽象觀察者:爲具體的觀察者定義了一個接口
三、具體被觀察者:對應一個具體的主題,在自身主題的內部發生變化時,通知集合中的全部觀察者
四、具體觀察者:依賴具體的被觀察者,對應它的主題,實現接收通知的接口。微信

具體實現

你們都熟悉這麼一個場景,咱們訂閱了不少了微信公衆號,這些微信公衆號後臺都有管理員在運營,當他們在後臺發佈了一篇推文,咱們這些訂閱了的用戶均可以收到這篇推文,微信公衆號就是被觀察者,訂閱的用戶就是觀察者。ide

1.定義抽象被觀察者接口

/**
 * 抽象被觀察者接口,定義添加,移除和通知觀察者的接口
 */
public interface Observable {

    public void registerObserver(Observer observer);

    public void removeObserver(Observer observer);

    public void notifyObserver();

}
複製代碼

2.定義抽象觀察者接口

/**
 * 抽象觀察者接口,定義接收通知方法
 */
public interface Observer {

    public void updateMessage(String message);
}
複製代碼

3.定義具體被觀察者類,表示一個特定主題(微信公衆號),包含一個List集合,存儲與之關聯的觀察者,對其進行管理(添加,移除和發送通知)

/**
 * 被觀察者,微信公衆號/服務號/訂閱號
 * 實現了Observable,實現添加訂閱者,刪除訂閱者,通知訂閱者的基本功能
 */
public class WechatServer implements Observable{

    private List<Observer> observers;

    private String message;

    public WechatServer() {
        observers = new ArrayList<>();
    }


    @Override
    public void registerObserver(Observer observer) {
        if (observers == null) {
            observers = new ArrayList<>();
        }
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        if (observers == null || observers.isEmpty()) {
            return;
        }
        observers.remove(observer);
    }

    @Override
    public void notifyObserver() {
        if (observers == null) {
            return;
        }
        for (Observer observer : observers) {
            observer.updateMessage(message);
        }
    }

    public void publicMessage(String message) {
        if (StringUtils.isBlank(message)) {
            throw new IllegalArgumentException("不能發佈空消息");
        }
        this.message = message;
        System.out.println("微信公衆號管理員發佈信息:"+message);
        //通知全部訂閱者
        notifyObserver();
    }
}
複製代碼

4.定義具體觀察者類,依賴微信公衆號這一主題的就是訂閱用戶

public class WechatUser implements Observer{

    private String name;

    private String message;

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

    @Override
    public void updateMessage(String message) {
        this.message = message;
        System.out.println(name+"收到推送消息:"+message);
    }
    
}
複製代碼

5.測試用例

public static void main(String [] args) {
        //定義微信公衆號
        WechatServer server = new WechatServer();

        //定義三個訂閱的用戶
        WechatUser user1 = new WechatUser("喬峯");
        WechatUser user2 = new WechatUser("令狐沖");
        WechatUser user3 = new WechatUser("楊過");

        //三人訂閱了公衆號
        server.registerObserver(user1);
        server.registerObserver(user2);
        server.registerObserver(user3);

        //微信公衆號發佈消息
        server.publicMessage("JAVA是最流行的語言!!");

        //喬峯取消了訂閱
        server.removeObserver(user1);
        //微信公衆號再次發佈消息(取消訂閱的用戶鄭光宇就收不到消息了)
        server.publicMessage("JAVA是最好用的語言!!");

    }
複製代碼

運行結果:測試

相關文章
相關標籤/搜索