觀察者模式與事件委托
阿新 • • 發佈:2018-03-23
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
觀察者模式與事件委托