亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

關于Observer模式不得不說的二三事

系統 1532 0

?? 今天有同事問我關于Observer模式的一個問題,說觀察者(Observer)為什么要依賴于主題(Subject),如下圖所示:


關于Observer模式不得不說的二三事
?

?

??? 從上圖可以看出,具體的觀察者對具體的主題有一個依賴, 而且從JDK本身提供的Observer接口,我們也可以看到,確實對主題(在JDK的實現中,為Observable接口)有一個依賴,如代碼所示:

?

    public interface Observer {
    void update(Observable o, Object arg);
}
  

??

?

?? 這個是為什么呢,為什么這里會依賴主題對象?其實這個跟Subject與Observer之間通訊的方式有關,當Subject本身狀態發生變化時,會去通知注冊了的Observer(即調用每個observer的update()方法),那么這個時候,主題本身要怎么樣去給Observer傳輸其需要的數據呢?

??

?? 在我們看到的大多數觀察者的實現中,主題(Subject)在通知注冊的Observer時,都會把Observer所需要的數據封裝好,傳給Observer,這個也就是所謂的‘推’的模式,主題主動將數據推給觀察者,這種情況下,Observer的接口往往定義如下:

??????

    public interface Observer {
    void update(Object arg);//從主題傳入的數據
}

  

?

?? 在這種‘推’的模式下,觀察者本身是不依賴于主題對象的。 但還有另外一種所謂‘拉’的通訊方式,是指觀察者在需要數據的時候主動從主題對象中獲取,這個情況下面就會出現觀察者依賴于主題對象,

???

    public interface Observer {
    void update(Subject subject); 
}
  

?

??? 由于這種拉的實現方法出現的比較少,而且‘拉’數據的模式有一個比較大的缺點,那就是出現了主題對象和觀察者對象之間的循環依賴,處理不好則很容易出來死循環。

???

???? 但是對于一個完整的觀察者模式來說,這兩種數據傳輸的方式都是需要的,這也就是JDK的Observer接口中的update()方法要有兩個參數的原因(Obervable對象一般對應于拉模式,Object對象一般對應于推模式),如果你做過Swing編程,你會發現在Swing的事件處理中,listner(實際上就是Observer)所接受的參數也支持推拉兩種數據方式,如

?????

    public interface MouseListener extends EventListener {
    public void mouseClicked(MouseEvent e);

    。。。其他略
}
  

??? 這里的MouseEvent對象實際上也包含了數據來源對象(觸發事件的對象),即具體主題對象,而除了主題對象之外的其他屬性,我們都可以看成是推模式中所傳的數據。

?

???? 好了,解決了同事了疑問,還需要點明Observer模式的另一職責。由于我們大多數的Observer模式的實現都很簡單,在這樣的實現下,主題對象大多只擁有一個職責,那就是管理Observer的職責(包括通知Observer),

????

    class ConcreteSubject implement ISubject
{
    private List observers=..
    public void addObserver(Observer obs)
    {
         //add observer
    }
    
    public void removeObserver(Observer obs)
    {
         //remove observer
    }

    public void notifyObservers(Object obj)
    {
        //notify observers
    }

}
  

?

??? 加上Observer模式是為了解決一對多的關系,久而久之,導致大多數人都忘記了主題對象(Subject)本身還應該有另一個職責,管理Observer只是主題(Subject)對象應有的共同的職責,不要忘了,還有多主題對象這么一回事。舉個以前看到的例子,

??? 假設我們的主題對象需要從遠程獲取一些數據,并分別的將其記錄在DB中,和顯示在Screen上,那么套用Observer模式,可以表示為:

????
關于Observer模式不得不說的二三事
?

?? 其中,DBObserver將拿到的數據寫到DB中,而DisplayObserver將拿到的數據顯示在SCREEN上,而MessagesSubject則有了兩個職責,一個是我們前面說的管理Observer的職責,另一個是去遠程取數據的職責,而這個我認為才是主題對象(Subject)應該有的具體的職責。

??

    public class MessagesSubject extends AbstractSubject implements Runnable
{

//管理Observer的職責會從AbstractSuject中獲得

//真正的業務邏輯
public void run()
{
    //從遠程獲得messages
    //通知觀察者
}
  

?

??? 完成一個完整的Observer模式很難,考慮的東西比較多(光是通知Observer這部分就有幾種不同的實現方式),不推薦每次都需要實現一個很完整的Observer模式,但是我們不應該遺忘這些構成完整Observer模式鎖需要的部分。

?

?

?

關于Observer模式不得不說的二三事


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产原创麻豆精品视频 | 欧美80岁老妇一级毛片 | 瑟瑟视频在线观看 | 国产精品国产精品国产专区不卡 | 一级网站片 | 欧美日韩乱码毛片免费观看 | 国产精品一区二区久久不卡 | 国产亚洲欧美日韩综合综合二区 | 久久久久久久久久久福利观看 | 欧美性大战久久久久久久蜜桃 | 97影院理论片 | 成人黄色在线免费观看 | 欧美国产成人精品一区二区三区 | 91视频免费观看高清观看完整 | 人人看操| 综合黄色 | 炮房五月| 愉拍自拍视频在线播放 | 成人在线免费网站 | 黑人巨大精品战中国美女 | 久久99精品久久久久久牛牛影视 | a毛片在线 | 四虎国产精品永久地址49 | 亚洲欧美中文字幕在线网站 | 国产一区二区三区在线观看免费 | 四虎影视2022入口网址 | 无码免费一区二区三区免费播放 | 免费特黄级夫费生活片 | 国产精品女在线观看 | 久久性精品 | 国产精品一区在线播放 | 久久久精品久久久久三级 | 国产精品免费一级在线观看 | 成人免费黄色片 | 国产视频一区二 | 亚洲天堂欧美 | 在线欧美精品国产综合五月 | 日本高清免费不卡视频 | 久久这里只有精品9 | 婷婷久久综合 | 欧美特黄一级大黄录像 |