<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    lyl3333489

    2007年7月10日

    騎警

    posted @ 2007-07-20 17:28 AAAAA 閱讀(299) | 評(píng)論 (1)編輯 收藏

    觀察者模式

        常聽說這么一句話(大意是這樣):不必可以去套用設(shè)計(jì)模式,如果按照面向?qū)ο蟮幕驹瓌t編程,自然是優(yōu)雅的設(shè)計(jì),即使沒有刻意使用模式,設(shè)計(jì)也會(huì)近乎于模式。開始感覺有一點(diǎn)玄,但在看了《C#設(shè)計(jì)模式縱橫談》視頻后,覺得有所收獲。下面,就參考視頻的內(nèi)容,嘗試著寫這么一個(gè)過程:根據(jù)面向?qū)ο蟮囊话阍瓌t對(duì)設(shè)計(jì)進(jìn)行重構(gòu),逐漸演化出觀察者模式。
    涉及的面向?qū)ο笤O(shè)計(jì)原則:單一職責(zé)原則、封裝變化、面向接口編程、依賴倒置原則、開閉原則。

    1.發(fā)布訂閱模型:



             
                   
    假如有需求如下:

    銀行需要把帳戶的如匯款、轉(zhuǎn)賬或取款等操作通知用戶,途徑包括手機(jī)短信、 email等。如圖所式。

    自然地,我們可以這樣做:

    public class ATM
     {
         BankAccount bankAccount;
         
         
    public void process()
         {
              
    //bankAccount...
             this.sendEmail(userEmail);
             
    this.sendPhone(phoneNumber);
         }
     
         
    private void sendEmail(String userEmail)
         {
             
    //
         }

        
    private void sendMobile(String phoneNumber)
         {
             
    //
         }
     }

    ATM機(jī)的 process()方法在處理完業(yè)務(wù)邏輯后,由email和phone通知用戶。

    2.初步重構(gòu)

    好像有bad smells,恩,根據(jù)單一職責(zé)原則。新增Email類和Phone類,并把相關(guān)業(yè)務(wù)邏輯改到BankAccount類完成。于是我們的代碼可以這樣:


    public class ATM
    {
        BankAccount bankAccount;
        
        
        
    public void process()
        {
              
    //
              bankAccount.withDraw();
        }
     
     }

    public class BankAccount 
    {
        Email email;
        Mobile mobile;

        
    public void withDraw()
        {
             
    //
             email.sendEmail(userEmail);
             mobile.sendMobile(phoneNumber);
        }
    }

    public class Email
    {
        
    public void sendEmail(String userEmail)
        {
        }
    }

    public class Mobile
    {
        
    public void sendMobile(String phoneNumber)
        {
        }
    }

    下面是代碼的UML圖:




    3.擁抱變化

    這個(gè)解決方案有問題嗎?可能沒有問題。它實(shí)現(xiàn)了我們的需求:在帳戶有操作變動(dòng)的時(shí)候,通知Email和Mobile去發(fā)送信息給用戶。但這樣設(shè)計(jì)就足夠了嗎?可能足夠了,可能還不夠。
    考慮如下兩種情況:
    1.在很長(zhǎng)一段時(shí)間里,訂閱方式很穩(wěn)定,比如系統(tǒng)只通過郵件和手機(jī)短信進(jìn)行信息訂閱,那么這個(gè)實(shí)現(xiàn)沒有太大問題;
    2.在近一兩年或更短的時(shí)間,更多的訂閱方式將會(huì)源源不斷地被加進(jìn)來:比如可以登錄官方網(wǎng)站等等,那這個(gè)實(shí)現(xiàn)就有問題:再看一下我們的UML圖,類BankAccount依賴于Email和Mobile類!就是說,如果需要添加新的訂閱方式ATM類的process()方法勢(shì)必要重新設(shè)計(jì)!

    于是我們的BankAccount類不得不變成:

    public class  BankAccount
    {
        Email email;
        Mobile mobile;
        Web web;

        
    public void withDraw()
        {
              
    //
             email.sendEmail(userEmail);
             mobile.sendMobile(phoneNumber);
             web.sendWeb(webSite);
        }
     
     }

    如果還有另一種方式,那么process()方法就又會(huì)需要加入:otherSubscribe.send...();等方法,另外如果訂閱類的接口(這里指sendEmail等方法)發(fā)生變化,BankAccount的withDraw()方法也必須有相應(yīng)的變化!這當(dāng)然是種災(zāi)難。我們必須改變這種情況。
    先解決遺留問題:第一種情況:訂閱方式相對(duì)穩(wěn)定的情況下呢?不改動(dòng)會(huì)產(chǎn)生災(zāi)難嗎?
    個(gè)人認(rèn)為:不會(huì)。比如某個(gè)系統(tǒng)信息只通過手機(jī)短信訂閱,那就沒有必要太在意這個(gè)問題。考慮周全一點(diǎn)不好嗎,如果將來有類似需求呢?小心過度設(shè)計(jì)!為了將來可能出現(xiàn)需求而進(jìn)行的預(yù)先設(shè)計(jì)并不太好。有需求,才有設(shè)計(jì)。

    現(xiàn)在來看解決之道:

    運(yùn)用面向?qū)ο蟮乃枷耄橄蟪鰡栴}所在。BankAccount類依賴于 Email類和Mobile類,而Email和Mobile是具體的類,ATM依賴于具體的類了,而且還不止一個(gè)!回憶一下依賴倒置原則:具體應(yīng)該依賴于抽象,底層模式應(yīng)該依賴于高層模式那怎么實(shí)現(xiàn)依賴倒置原則呢?面向?qū)ο缶幊讨杏幸粭l總的原則:封裝變化。如何實(shí)現(xiàn)封裝變化?需要我們這樣:面向接口編程

    回顧一下:我們?cè)谠O(shè)計(jì)中實(shí)現(xiàn)類依賴了具體的類,違反了依賴倒置原則。為了遵循依賴倒置原則,我們采用面向接口編程的方法,從而實(shí)現(xiàn)了面向?qū)ο蟮囊粭l總的原則:封裝變化。


    看代碼:

    public interface AccountObserver
    {
        
    public void upDate(UserAccount userAccount);
    }

    public class Email implements AccountObserver
    {
        
    public void upDate(UserAccount userAccount)
        {
        }
    }

    public class Mobile
    {
        
    public void upDate(UserAccount userAccount)
        {
        }
    }

    public class BankAccount 
    {
        List 
    <AccountObserver> observer = new ArrayList<AccountObserver>;

        
    public void withDraw()
        {
             
    //
             for (AccountObserver ao : observer)
             {
                ao.upDate(userAccount)
              }
        }
        
        
    public void addOberver(AccountObserver accountObserver)
        {
              observer.add(accountObserver);
         }
    }

    UML圖:



    現(xiàn)在,BankAccount依賴于interface AccountObserver。Email和Mobile實(shí)現(xiàn)AccountObserver接口。通過遵循面向接口編程遵循了依賴倒置原則

    4.開閉原則

    終于修改好了,我們解決了訂閱者變化的問題。但如果發(fā)布者也傾向于變化呢?這就牽涉到面向?qū)ο罄锏牧硪粋€(gè)原則:開閉原則即:對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。具體怎么做呢?通過抽象類,從抽象類繼承具體類。
    看最終的代碼(只寫幾個(gè)關(guān)鍵的方法,全貌可看最后的UML圖):

    訂閱:

    public interface AccountObserver
    {
        
    public void upDate(UserAccount userAccount);
    }

    public class Email implements AccountObserver
    {
        
    public void upDate(UserAccount userAccount)
        {
        }
    }

    public class Mobile implements AccountObserver
    {
        
    public void upDate(UserAccount userAccount)
        {
        }
    }


    發(fā)布:



    public abstract class Subject
    {
         List 
    <AccountObserver> observer = new ArrayList<AccountObserver>;

        
    protected void withDraw()
        {
             
    //
             notify();
             
        }
        
        
    protected void notify(UserAccount userAccount)
        {
             
    for (AccountObserver ao : observer)
             {
                ao.upDate(userAccount)
              }
         }
        
        
    protected void addOberver(AccountObserver accountObserver)
        {
              observer.add(accountObserver);
         }

          
    protected void deleteOberver(AccountObserver accountObserver)
        {
              observer.remove(accountObserver);
         }

    }

    public class BankAccount extends Subject
    {
        
    public void withDraw()
        {
             
    //
             for (AccountObserver ao : observer)
             {
                ao.upDate(userAccount)
              }
        }
        
    }



    看UML圖:




    5.觀察者模式概況




    這就是觀察者模式了,對(duì)比一下官方的UML圖,是不是一目了然了呢?
    稍作說明(這里的依賴都是指廣義的依賴):
    1.被觀察者ConcreteSubject繼承自Subject抽象類;
    2.Subject抽象類依賴于觀察者Observer抽象接口;
    3.觀察者ConcreteObserver實(shí)現(xiàn)Observer 接口;
    4.觀察者ConcreteObserver間接依賴于ConcreteSubject類。
    如果要增加具體的觀察者,只要再實(shí)現(xiàn)Obsever接口即可,而被觀察方不需要做任何修改。而如果需要修改被觀察者,只要從Subject抽象類繼承即可。

    posted @ 2007-07-10 10:36 AAAAA 閱讀(323) | 評(píng)論 (0)編輯 收藏

    收集的網(wǎng)址

    http://www.linuxfans.org   
    http://www.otasuke.ne.jp/modules/xwords/index.php   
    http://jp.hjenglish.com/papers.aspx   
    www.21cnhr.gov.cn   
    http://www.ytv.co.jp/conan/   
    http://www13.tianya.cn/new/Publicforum/Content.asp?idWriter=3915484&Key=228823315&strItem=no04&idArticle=483393&flag=1   
    http://piano.stedu.net/   
    http://www.nhk.or.jp/           <<NHK>>           http://www.nhk.or.jp/r-news/   
    http://www.intel.com/software/cn/mcwebcast/#slide=1    intel class   
    http://www.yangmi.net/ky/Print.asp?ArticleID=13801   !!!   
    http://bbs.i18.cn/index.asp     中國(guó)零售網(wǎng)   
    http://www.fortunespace.net/forum/    中國(guó)財(cái)富論壇   
    http://www.yesky.com/SoftChannel/72357786515668992/20040129/1764106.shtml  求和   
    http://www.yesky.com/SoftChannel/72348968914255872/20050126/1905902.shtml Excel ?用   
    http://www.yesky.com/soft/office/excel-news/his/his_4.shtml  Excel   
    http://www.4399.net/flash/1602_2.htm?800 golden   
    http://edu.itbulo.com/200511/58025.htm        ITbulo   
    http://202.103.49.240/jsjzs/excel/excelyy.htm    Excel 排序   
    http://192.168.1.23/use_wf/Dep_App     WF  WF  WF  WF   
    http://www.yodian.com   有點(diǎn)   
    http://www.dlsp.com.cn   DLSP   
    http://64.233.179.104/search?q=cache:QqZYnKlqqEwJ:members.at.infoseek.co.jp/skillup/yougo/yougo6.htm+EOB%E3%80%80Electronic&hl=ja&gl=jp&ct=clnk&cd=1&lr=lang_ja   
    http://www.codesky.net   CODE   
        
    http://www1.tianya.cn/new/TechForum/Content.asp?idWriter=3915484&Key=840161655&idItem=81&idArticle=251915   
    http://www.chinacs.net/archives/8/2004/12/12/3188.html       C#   
    http://music.whnews.cn/playgame/flashshow.php?flashid=895      SC   
    http://www.tianya.cn/new/TechForum/Content.asp?idWriter=3915484&Key=481775086&idItem=81&idArticle=562447   
    http://192.168.1.211/TRIAL/upload/jinji/study/access/    ACCESS   
    http://www.wswire.com/      huaerjie dianxun   
    http://infoseek.amikai.com/amitext/indexUTF8.jsp   
    http://www.51windows.net/pages/ado/?url=/pages/ado/mdmthaddnew.htm      ADO    ADO 
    http://www.51windows.net/
      
    http://www.codechina.net/resource/sort.php/621/4       Access VBA  Code   
    http://jakarta.apche.org        struts   
    http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/csref/html/vcoricsharptutorials.asp       MSDN c#   
    http://www.daliancity.com.cn/job/index.php     DLZX 
    http://www.cjsdu.com/   DuiRiLunTan


    http://www.mutouyu.com/translation/ 木頭魚翻訳

    http://www6.tianya.cn/new/techforum/Content.asp?idWriter=3915484&Key=700727019&idItem=81&idArticle=574220

    http://localhost:8080/solves4/pages/CM/AAA/CMAAA001R.jsp

    http://www.tianya.cn/new/techforum/Content.asp?idWriter=3915484&Key=292720848&idItem=81&idArticle=568508

    http://www1.tianya.cn/new/techforum/Content.asp?idWriter=3915484&Key=189209006&idItem=81&idArticle=573983

    http://www2.tianya.cn/new/techforum/Content.asp?idWriter=3915484&Key=677920263&idItem=81&idArticle=573828
     hua xian chuang guan

    http://www.4399.net/flash/4362_4.htm?1024
     pao tai TD

    http://www.excite.co.jp/world/chinese/
     onlineTranslate

    http://www.4399.net/flash/457_1.htm?800
     qiJi

    http://www.javaeye.com/
     
    http://www.andykhan.com/jexcelapi/
     JXL(JAVA Excel API)

    http://www.uml.org.cn/sjms/200703274.asp
     設(shè)計(jì)モード

    http://www.okajax.com/
     Ajax 中國(guó)

    http://www.nicenic.com/domain/
     域名


    域名最長(zhǎng)的網(wǎng)站
    http://www.llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk/
    http://www.111111111111111111111111111111111111111111111111111111111111.com/
    http://3.141592653589793238462643383279502884197169399375105820974944592.com/
    http://www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com/

    幾個(gè)不錯(cuò)的JAVA學(xué)習(xí)網(wǎng)站
    http://www.csdn.net(社區(qū)、文檔、bolg、知識(shí)庫)
    http://www.hibernate.org.cn
    http://m.tkk7.com
    http://www.jdon.com
    http://www.javafan.net
    http://www.open-open.com
    http://dev2dev.bea.com.cn/
    http://www.javaresearch.org/
    http://www.codechina.net/resource/
    http://gceclub.sun.com.cn
    http://www.javaeye.com
    http://WWW.chinaitlab.com  中國(guó)IT試験室

    您的Blog地址是:http://m.tkk7.com/lyl3333489/

     

    posted @ 2007-07-10 09:05 AAAAA 閱讀(252) | 評(píng)論 (0)編輯 收藏

    <2007年7月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(1)

    隨筆檔案

    相冊(cè)

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 1a级毛片免费观看| 男人的天堂亚洲一区二区三区 | 久久精品国产亚洲网站| 四虎成人精品永久免费AV| 亚洲人成小说网站色| 最新精品亚洲成a人在线观看| aⅴ免费在线观看| 日韩少妇内射免费播放| 亚洲国产精品yw在线观看| 免费萌白酱国产一区二区| 91精品国产免费网站| 亚洲色少妇熟女11p| 国产精品亚洲精品日韩已满| 中国在线观看免费高清完整版| A毛片毛片看免费| 亚洲色少妇熟女11p| 老司机亚洲精品影院无码 | 亚洲日本一区二区一本一道| 猫咪免费人成网站在线观看| jizz免费观看视频| 中文字幕乱码亚洲精品一区| 久久被窝电影亚洲爽爽爽| 在线观看无码的免费网站| 国产无遮挡裸体免费视频在线观看 | 污视频在线免费观看| 男女啪啪免费体验区| 国产精品亚洲四区在线观看| 亚洲精品无码精品mV在线观看| 精品无码国产污污污免费| 69式互添免费视频| 老司机69精品成免费视频| 人妻免费久久久久久久了| 亚洲男同gay片| 亚洲AV一二三区成人影片| 亚洲视频免费在线观看| 亚洲综合色成在线播放| 国产yw855.c免费视频| 久久受www免费人成_看片中文| 日韩精品在线免费观看| 中文字幕成人免费高清在线| 粉色视频成年免费人15次|