乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      實用設(shè)計模式之觀察者模式

       joy_chen 2015-03-28

      1.什么是觀察者模式

              觀察者模式是軟件設(shè)計模式的一種。在此種模式中,一個目標(biāo)物件管理所有相依于它的觀察者物件,并且在它本身的狀態(tài)改變時主動發(fā)出通知。 

      2.觀察者模式的實現(xiàn)

              雖然在Java中提供了現(xiàn)成的Observer和Observable實現(xiàn),但由于Observable已經(jīng)被實現(xiàn)成class,所以當(dāng)需要將自己的某個業(yè)務(wù)類實現(xiàn)成可被觀察的特性時,往往還是得自己來實現(xiàn),因此下文不再使用Java中的Observable和Observer類,而是自行實現(xiàn)。

              通常的實現(xiàn)方式是注冊-通知-取消注冊。代碼如下:

      1. public interface Listener {  
      2.     void onNotify();  
      3. }  
      4.   
      5.   
      6. public class Subject {  
      7.     private List<Listener> listeners;  
      8.     private Object value;  
      9.       
      10.     public Subject(){  
      11.         listeners=new ArrayList<Listener>();  
      12.         value=new Object();  
      13.     }  
      14.       
      15.     public void registe(Listener listener){  
      16.         listeners.add(listener);  
      17.     }  
      18.       
      19.     public void unRegiste(Listener listener){  
      20.         listeners.remove(listener);  
      21.     }  
      22.       
      23.     private void sendNotify(){  
      24.         for(Listener listener:listeners){  
      25.             listener.onNotify();  
      26.         }  
      27.     }  
      28.       
      29.     public Object getValue(){  
      30.         return value;  
      31.     }  
      32.       
      33.     public void setValue(Object value){  
      34.         if (!this.value.equals(value)){  
      35.             this.value=value;  
      36.             sendNotify();  
      37.         }  
      38.     }  
      39. }  


      2.1.容器的選擇

              被觀察者需要一個容器來保留注冊進(jìn)來的觀察者引用,上文的代碼中使用了List作為容器,這個容器的選擇會影響到整體的實現(xiàn)方案。

              通常選擇用一個Array或List容器來存儲,這樣一方面可以做到有序,另一方面在通知時方便遍歷。

              如果不想有重復(fù)的觀察者引用,則要么在注冊時檢查是否已經(jīng)存在于容器中,比如在上文registe()方法中加入contains()的判斷,要么就選擇不可重復(fù)的容器如Set,Map等。這樣的容器本身已經(jīng)包含了對重復(fù)的處理,但也意味著在發(fā)送通知時的順序不是注冊時的先后順序。 

      2.2.通知后的數(shù)據(jù)獲取方式

              也就是常說的‘推’或‘拉’。推方式是說變化的數(shù)據(jù)隨著對觀察者的接口調(diào)用以參數(shù)的方式傳遞給觀察者。拉方式是說對觀察者的接口調(diào)用只用于通知數(shù)據(jù)發(fā)生了變化這件事情,由觀察者自行調(diào)用被觀察者的getXXX()方法取得感興趣的數(shù)據(jù)。前者不管三七二十一把變化就推給觀察者了,不管你有用沒用;后者只是盡到通知的義務(wù),你對什么數(shù)據(jù)感興趣就自己來拿。這個要根據(jù)實際的設(shè)計情況進(jìn)行決策。

              上文的代碼中使用了拉的方式,當(dāng)value發(fā)生變化時,會通過sendNotify()方法發(fā)送通知給Listener,但通知中未攜帶value的值,而是由Listener一方根據(jù)情況調(diào)用getValue()方法來拉取變化后的新的value值。 

      2.3.通知后的取消注冊

              通知后的取消在實際應(yīng)用中也沒有上述示例代碼這樣簡單。一個典型的需求就是某個Listener要在onNotify()方法執(zhí)行的過程中調(diào)用unRegiste(this)。對這一需求的滿足可以小心的處理sendNotify()方法,也可以通過標(biāo)識位進(jìn)行標(biāo)識,還可以在sendNotify()中不使用原始的容器而是遍歷一個副本,無論怎樣,這個需求很容易發(fā)生,在實現(xiàn)觀察者模式時要進(jìn)行處理。 

      2.4.其他問題

              如果Subject是時間相關(guān)的業(yè)務(wù),就要對每一個listener的運行時間加以約束,要能對每一個onNotify的調(diào)用時間進(jìn)行監(jiān)控并處理,以保持對每一個Listener的時間分配在一個合理的范圍內(nèi)。或者使用異步、多線程方式調(diào)起onNotify()。

              如果Subject需要實現(xiàn)按優(yōu)先級進(jìn)行通知,那就要在優(yōu)先級隊列管理及通知調(diào)度上下功夫了。 

      3.總結(jié)

              觀察者模式說得多,用得多,但在實際工作當(dāng)中,要深入思考而不是完全照搬示例代碼,這也是設(shè)計模式給我們的,要學(xué)會把它變成自己的經(jīng)驗。



        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多