1. 程式人生 > >觀察者模式與事件委托

觀察者模式與事件委托

implement pat pos status string sub 通知 serve handle

情景

  • 平時很多人都會用新浪微博, 關註女神動態, 女神就是通知者,也叫主題, 而關註女神的這些人,就是觀察者,也叫訂閱者, 既然訂閱了女神的動態, 如果女神有新的動態, 我們就會想通過某一個渠道被通知, 這種交互方式就是觀察者模式

常見的使用場景;

  • spring中的event, listener等都是觀察者模式

代碼實現

 /**
     * 通知者, 也是主題發布者, 就是為了被觀察或者訂閱的,
     * 主題如果狀態發生改變,就會通知所有的訂閱者(觀察者)
     */
public interface Subject {
    void addFans(Observer fans);
    void deleteFans(Observer fans);
    void notifyFans();

    void addFansWithEventListener(Observer fans, String event);
    void statusChange();
}
  /**
     * 屌絲朋友們都愛關註的劉亦菲仙女
     */
public class LiuYiFei implements Subject {
    @Override
    public void addFans(Observer fans) {
        fansWithEventListener.put(fans, null);
    }

    @Override
    public void deleteFans(Observer fans){
        fansWithEventListener.remove(fans);
    }

    /**
     * 記錄每個對象的回調事件
     * 模擬了 c# eventhandler liuyifei.update += zhangsan.getinfobyemail //大話設計模式 14
     */
    private Map<Observer, String> fansWithEventListener =  new HashMap<>();

    /**
     * 通知所有的粉絲兒, 面條兒....
     */
    @Override
    public void notifyFans() {
        for (Observer fans : fansWithEventListener.keySet()) {
            if(fansWithEventListener.get(fans) == null){
                //默認采用qq通知
                fans.getInfoByQQ();
            }else{
                //如果有自己註冊的事件, 就采用指定的通知方式通知
                try {
                    fans.getClass().getDeclaredMethod(fansWithEventListener.get(fans)).invoke(fans) ;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void addFansWithEventListener(Observer fans, String event) {
        fansWithEventListener.put(fans, event);
    }

    /**
     * 女神的狀態改變, 所有訂閱者第一時間收到消息
     */
    @Override
    public void statusChange() {
        this.notifyFans();
    }
}
/**
     * 事件委托模型: 訂閱的時候順便制定通知的方式
     * 基礎的觀察者模式通知方式比較單一, 只能通過一條路徑通知訂閱者
     * 現在我們有微信, 有扣扣, 有郵箱, 我們需要自己指定通過什麽渠道來訂閱通知
     */
public interface Observer {
    
    //主題發生改變時的通知渠道
    void getInfoByQQ();

    //主題發生改變時使用微信通知
    void getInfoByWeiXin();

    //主題發生改變時使用郵件通知
    void getInfoByEMail();
}
public class ZhangSan implements Observer {
    @Override
    public void getInfoByQQ() {
        System.out.println("我是張三, QQ通知: 女神更新狀態了!!");
    }

    @Override
    public void getInfoByWeiXin() {
        System.out.println("我是張三, 微信通知: 女神更新狀態了!!");
    }

    @Override
    public void getInfoByEMail() {
        System.out.println("我是張三, 郵箱通知: 女神更新狀態了!!");
    }
}
public class LiSi implements Observer {
    @Override
    public void getInfoByQQ() {
        System.out.println("我是李四,QQ通知: 女神更新狀態了!!");
    }

    @Override
    public void getInfoByWeiXin() {
        System.out.println("我是李四,微信通知: 女神更新狀態了!!");
    }

    @Override
    public void getInfoByEMail() {
        System.out.println("我是李四,郵箱通知: 女神更新狀態了!!");
    }
}
/**
 * 王二麻子實現訂閱接口就可以有獲取新動態的能力
 */
public class WangerMaZi implements Observer {

    /**
     * 訂閱了菲菲女神微博後, 女神發新狀態通知王二麻子的渠道
     */
    @Override
    public void getInfoByQQ() {
        System.out.println("我是王二麻子, QQ通知: 女神更新狀態了!!");
    }

    @Override
    public void getInfoByWeiXin() {
        System.out.println("我是王二麻子, 微信通知: 女神更新狀態了!!");
    }

    @Override
    public void getInfoByEMail() {
        System.out.println("我是王二麻子, 郵箱通知: 女神更新狀態了!!");
    }
}
public class TestEventHandler {
    /**
     * 女神劉亦菲更新微博狀態後發生什麽
     */
    @Test
    public void afterLiuyifeiUpdateWeibo(){
        Subject liuyifei = new LiuYiFei();

        Observer zhangSan = new ZhangSan();
        Observer liSi = new LiSi();
        Observer wangerMaZi = new WangerMaZi();

//        liuyifei.addListener(zhangSan, "微信通知");
//      liuyifei.addListener(lisiSan, "郵箱通知");
        //指定通知以後的回調方法
        liuyifei.addFansWithEventListener(zhangSan, "getInfoByWeiXin");
        liuyifei.addFansWithEventListener(wangerMaZi, "getInfoByEMail");
        liuyifei.addFans(liSi);

        liuyifei.statusChange();
    }
}

源碼路徑

https://github.com/offline7LY/designpattern/tree/master/observer

觀察者模式與事件委托