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

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

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

    我的隱式生活(My Implicit Life)

    繼續(xù)搞“對(duì)象”,玩OO.

    首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      11 Posts :: 1 Stories :: 39 Comments :: 0 Trackbacks

        說(shuō)起這個(gè)工廠模式,一時(shí)還真不知道該如何說(shuō)起。反正這是我的開(kāi)發(fā)日志,不提理論的東西,理論的東西那里都有,我只想把具體實(shí)踐記錄下來(lái)給師弟師妹們作個(gè)參考,積累點(diǎn)經(jīng)驗(yàn)。所有這些文字都是集中講一點(diǎn)――“在什么情況下為什么用某種模式好,為什么好,為什么在那種情況下能想起來(lái)用?”。

           研究生院項(xiàng)目中“明顯”使用了“工廠方法模式”。其實(shí)在遇到具體問(wèn)題的時(shí)候,即使我們不知道有這個(gè)模式存在,我們也肯定會(huì)造一個(gè)類(lèi)似的東西出來(lái)。但是,肯定沒(méi)有書(shū)上論述的那么好,那么全面。我想這就是看書(shū)的好處吧。

     

    工廠方法出現(xiàn)的必然(我的理解,一個(gè)很狹隘并幼稚理的人的理解)

     

           剛開(kāi)始使用這個(gè)東西的時(shí)候,只是感覺(jué)是單純的一種模式,用于創(chuàng)建需要的對(duì)象。

           但是隨著使用和思考的深入,越發(fā)發(fā)現(xiàn)它給我的啟示不只在于單純的對(duì)象創(chuàng)建,而是告訴我應(yīng)該怎么理解“產(chǎn)品”,怎么得到“產(chǎn)品”,怎么消費(fèi)“產(chǎn)品”,以至于以后怎么設(shè)計(jì)“產(chǎn)品”。

           下面這個(gè)線索是我對(duì)它出現(xiàn)必然性的理解:

    1.         “針對(duì)接口編程”

      這是OO世界中經(jīng)典的規(guī)范,不管你主動(dòng)還是被動(dòng),你天天都在用這個(gè)東西。

        接口是共性的表示,在對(duì)象的世界中,共性和個(gè)性的辯證關(guān)系是最重要的關(guān)系。在萬(wàn)千的對(duì)象中,通過(guò)它們之間的共性和個(gè)性,可以形成最基本對(duì)象層級(jí)架構(gòu)。

    假設(shè)我們的討論域中有以下一些對(duì)象:“學(xué)生”、“大學(xué)生”、“小學(xué)生”、“中學(xué)生”;我們不用細(xì)想,學(xué)過(guò)一天OO的人都可以為這些耳熟能詳?shù)膶?duì)象們,通過(guò)個(gè)性和共性的關(guān)系得出下面的結(jié)構(gòu)圖。

    o_1.JPG

     

           把這些對(duì)象之間的關(guān)系定義成這樣是順理成章的。

           下一步肯定是讓客戶端“使用”這個(gè)接口啦。也就是如下圖:

     

    o_2.JPG

    2.         接口和具體類(lèi)的矛盾

    勿庸置疑,我們只希望Client跟接口Student打交道,讓它根本就不知道Student有哪些子類(lèi),絕對(duì)不希望直接跟它們打交道。

    但這里出現(xiàn)的困難是,接口都是“假”的,都是由具體類(lèi)upcast的。

    如果Client要使用接口StudentClient中必須會(huì)出現(xiàn)下面的代碼:

    Student marco = new Small_Student();

           只要一出現(xiàn)這個(gè)代碼,就說(shuō)明Client不只跟Student打交道了,它知道了Small_Student類(lèi),這違反了我們預(yù)先的想法。

    3.         找“人”幫我去創(chuàng)建“接口對(duì)象”

        從上圖體現(xiàn)出來(lái)的結(jié)構(gòu)看,Client只想跟Student打交道的目的是實(shí)現(xiàn)不了的了。

           最簡(jiǎn)單的方法就是找另外的“幫手”去幫我生成這個(gè)“接口對(duì)象”。這個(gè)幫手它知道“接口對(duì)象”的具體類(lèi)型,但是它為客戶端提供的卻一定是“接口類(lèi)型”。這就符合我們的要求了。如圖:

    o_3.JPG

        這樣,Client就可以既用到了“Student接口對(duì)象”,又不用因?yàn)椤爸挥芯唧w類(lèi)才能創(chuàng)建對(duì)象”的規(guī)則,而必須對(duì)其子類(lèi)結(jié)構(gòu)有完全的了解。它成功的解決了2中的矛盾。

           而“負(fù)責(zé)創(chuàng)建具體類(lèi)對(duì)象的任務(wù)”全部都落在了這個(gè)“幫手”身上,這個(gè)“幫手”(Student_Factory)就是工廠模式中的工廠類(lèi),更具體的說(shuō),它就是“簡(jiǎn)單工廠模式”中的“簡(jiǎn)單工廠類(lèi)”。

           我覺(jué)得,即使一點(diǎn)都不知道工廠模式,一旦我遇到了2里說(shuō)的矛盾,我也會(huì)用這樣的方法處理。

    4.         這個(gè)“幫手”不符合“開(kāi)-閉原則”

    這個(gè)幫手的確不錯(cuò)了,而且一躍成為系統(tǒng)中最重要的對(duì)象了,所有“創(chuàng)建具體類(lèi)的邏輯”都放進(jìn)去了,也就是因?yàn)橹匾f(wàn)一掛了不就慘了。

    再者,它不符合“開(kāi)-閉”原則,我不能在不修改這個(gè)幫手的情況下添加任何一個(gè)產(chǎn)品。在這個(gè)例子中就是,如果那天我有病非要加一個(gè)“幼兒園學(xué)生”進(jìn)來(lái),那您就必須修改這個(gè)“幫手”的代碼了,這個(gè)“幫手”現(xiàn)在就變成Version2(如下圖)了,這個(gè)二版的幫手,可以在“代碼”層實(shí)現(xiàn)對(duì)一版(還沒(méi)有添加幼兒園學(xué)生之前)的通用,但這種保證在“開(kāi)-閉”原則看來(lái),還是不夠的,不保險(xiǎn)的,它要的是在類(lèi)的結(jié)構(gòu)上的保證。聲明一下,這是我很感性的理解,不正確的可能性很高。

    o_4.JPG

    5.         讓“幫手”也多態(tài)

    這里可以嘗試讓“幫手”也多態(tài)一下,這樣“每種學(xué)生類(lèi)創(chuàng)建的任務(wù)”都被分派到了多態(tài)出來(lái)的類(lèi)中去了。這時(shí),再有新的學(xué)生類(lèi)型加進(jìn)來(lái),添加一個(gè)對(duì)應(yīng)的幫手就可以了。這樣雖然類(lèi)多了一些,但是符合“開(kāi)-閉”原則,書(shū)上稱(chēng)之為“工廠方法模式”。如圖:

    o_5.JPG

        假如Client現(xiàn)在要使用一個(gè)小學(xué)生,代碼如下:

    1        //創(chuàng)建一個(gè)小學(xué)生工廠類(lèi)這個(gè)幫手
    2        Student_Factory factory = new Small_Student_Factory();
    3        //求助這個(gè)幫手,幫我創(chuàng)建一個(gè)

    4        Student primaryStudent = factory.produce();
    5        //這時(shí)就可以使用這個(gè)小學(xué)生了,讓它玩玩游戲吧

    6        primaryStudent.playGames();
    7

        在這里還是要強(qiáng)調(diào)兩點(diǎn):

    n         雖然實(shí)際上Client的確使用了一個(gè)小學(xué)生對(duì)象(Small_Student),但這里Client也認(rèn)為它就是Student對(duì)象,這里一定要用Student接口來(lái)隱藏它的具體類(lèi)。

    n         另外,卻不需要用Student_Factory這個(gè)接口來(lái)隱藏它的具體類(lèi),因?yàn)椋?/SPAN>Client實(shí)際就是通過(guò)“選擇它的具體類(lèi)”這招兒來(lái)“選擇創(chuàng)建的學(xué)生類(lèi)型”。這里的Student_Factory更多的功能不是“隱藏”具體類(lèi),而是“規(guī)范”具體類(lèi)。

     

    項(xiàng)目實(shí)踐

     

           扯淡到此,該聯(lián)系我們的項(xiàng)目啦。

           由于是做研究生院的項(xiàng)目,其中巨大的需求就是要讓同學(xué)能在網(wǎng)上提交各種申請(qǐng)單,申請(qǐng)退學(xué)的,申請(qǐng)轉(zhuǎn)專(zhuān)業(yè)的,申請(qǐng)復(fù)學(xué)的,申請(qǐng)保留學(xué)籍的,除了申請(qǐng)女朋友的外,應(yīng)有盡有。       對(duì)于這些單子,用最最基本OO思維,根據(jù)共性個(gè)性分析方式,抽象出一個(gè)申請(qǐng)單接口,和若干的具體類(lèi)。

           當(dāng)然,除了概念上感性上吻合以外,在項(xiàng)目中它們也要“真”的有巨大的共性才行,如都要提交,修改,刪除,審核,打印等功能。

           靠,既然都這樣了,肯定就用一接口規(guī)定它了。

           想到這里,加上有了上面的思考,不用說(shuō)了,就用工廠方法模式啦。

     

    o_6.JPG

        圖中Ent_Shift就是申請(qǐng)單接口。等于前面分析的Student接口。還可以看到有很多具體類(lèi),前面例子中是代表各種學(xué)生,這里就是代表各種申請(qǐng)單。

           當(dāng)然,這里還有很多工廠,也就是前面一直叫的“幫手”。

    o_7.JPG

           Bean_Shift就是工廠接口,相當(dāng)于前面的Student_Factory接口。還有很多的具體類(lèi)就是生產(chǎn)各種申請(qǐng)單的工廠類(lèi)。

           下面就是使用“申請(qǐng)單工廠方法模式”的一段客戶端代碼:

     1        //聲明申請(qǐng)單接口
     2        Ent_Shift es = null;
     3        //聲明申請(qǐng)單工廠接口

     4        Bean_Shift bs = null;
     5        //根據(jù)傳入的申請(qǐng)單類(lèi)型數(shù)字身成對(duì)應(yīng)的申請(qǐng)單工廠

     6        switch (shiftTypeID) {
     7            case
     Bean_Shift.SHIFT_CHANGETEAAP :
     8                bs = new
     Bean_Shift_CHANGETEAAP();
     9                break
    ;
    10            case
     Bean_Shift.SHIFT_RESERVEAP :
    11                bs = new
     Bean_Shift_RESERVEAP();
    12                break
    ;
    13            case
     Bean_Shift.SHIFT_RENEWAP :
    14                bs = new
     Bean_Shift_RENEWAP();
    15                break
    ;
    16             //省略了別的申請(qǐng)單……………………

    17            default :
    18                this.forwardErr(req, resp, "所選擇的異動(dòng)類(lèi)別不存在"
    );
    19        }

    20
    21        try 
    {
    22            //調(diào)用工廠接口的生產(chǎn)方法

    23            es = bs.getBlankShift(stuID);
    24
                
    25        }
     catch (Exception e) {
    26            this
    .forwardErr(req, resp, DB_ERROR);
    27        }

    28        //調(diào)用單子的提交方法
    29        es.submit(req);
    30
            
    31        //發(fā)給頁(yè)面去顯示

    32        es.fowrardWithSessionObject(
    33
                    req,
    34
                    resp,
    35
                    Ent_Shift.nameInSessionAndRequest);
    36

     

    升華

     

           個(gè)人比較同意《Design Pattern Explained》中作者講的,要用好很多的模式,其中都有一個(gè)思路,就是用接口或抽象類(lèi)來(lái)隱藏子類(lèi)的不同。

           我每當(dāng)看到這時(shí),老是會(huì)被一種思路困擾――“new只能new具體類(lèi)啊,這咋能隱藏呢,這隱藏還有什么用呢?”。

           作者仿佛也曾經(jīng)有過(guò)我的這個(gè)傻B苦惱,它的解決方法就是:根本在使用對(duì)象的時(shí)候,特別是設(shè)計(jì)階段,盡量不去想對(duì)象是在那里被new的。他認(rèn)為:反正有了工廠模式后,你總有辦法把他們new出來(lái)的。

           所以,我用了工廠模式后更發(fā)的啟發(fā)是:以后設(shè)計(jì)的時(shí)候不要想一個(gè)Client怎么創(chuàng)建一個(gè)對(duì)象,盡管放心大膽的先繼續(xù)想,直接使用就好了。反正最后我還有工廠模式呢。

           因此俺的副標(biāo)題才是“Ignore how they were created”,呵呵。
                                        MARCO ZHANG 2006年2月16日3:52:10

    posted on 2006-02-16 03:53 marco 閱讀(1397) 評(píng)論(9)  編輯  收藏 所屬分類(lèi): -=Design Pattern=--=Java Techs=--=Project Experience=-

    Feedback

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-02-16 09:38 飛翔的西瓜
    把你加入我的鏈接了,我會(huì)經(jīng)常來(lái)“監(jiān)督”你的進(jìn)程的:)  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-02-16 10:49 thekll
    ft~建議增加申請(qǐng)男朋友和女朋友的功能,這樣系統(tǒng)的可用性更強(qiáng)些  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-02-16 13:19 marco
    飛翔的西瓜,我就在此謝大哥您啦。

    我也把你鏈上了。  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-02-18 00:48 王知真
    blog好詳細(xì),呵呵,現(xiàn)在就是希望自己早一點(diǎn)再有一個(gè)技術(shù)blog,相互交流  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-02-18 21:10 龍卷風(fēng)
    好文章,不過(guò)個(gè)人感覺(jué)工廠模式不實(shí)用
    本來(lái)簡(jiǎn)單類(lèi)廠靜態(tài)函數(shù)可以省下一個(gè)new,但工廠模式創(chuàng)建工廠還是需要new出來(lái)。
    我喜歡使用利用了反射機(jī)制的簡(jiǎn)單類(lèi)廠,既滿足開(kāi)閉原則也用起來(lái)也舒服。  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-03-01 12:10 grakiss
    也許是我認(rèn)識(shí)不夠,但是同樓上一樣的想法,在生成具體的類(lèi)工廠時(shí)仍然會(huì)需要去確定它的具體類(lèi)型,那么所謂的封裝,隱藏不是因此而失效了么?這也正是你自己一開(kāi)始的想法.雖然你提到可以不用去考慮具體的生成過(guò)程,但這不正是使用該模式的關(guān)鍵之處嗎,我無(wú)法明白不考慮這個(gè)的情況下使用類(lèi)工廠模式的意義.另外對(duì)樓上所說(shuō)的反射機(jī)制很感興趣,似乎有另外的實(shí)現(xiàn)方法.  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-03-02 14:21 marco
    grakiss,對(duì)于客戶端來(lái)講,所謂的工廠就是用來(lái)封裝“更里面”的“抽象-具體”也就是“接口-具體類(lèi)”的層級(jí)結(jié)構(gòu),讓客戶端能“只”關(guān)注抽象也就是接口。

    所以,換句話講,在工廠方法模式中,對(duì)工廠的層級(jí)結(jié)構(gòu)中,的確如你所說(shuō),是不能隱藏工程的具體類(lèi)了。

    但是,你再換個(gè)思路想想,由這個(gè)工廠層級(jí)結(jié)構(gòu),更里面的層級(jí)結(jié)構(gòu),如這個(gè)例子中的各種學(xué)生的具體類(lèi)型,真的對(duì)于客戶端已經(jīng)隱藏起來(lái)了,而只把抽象的接口暴露給了客戶端。

    所以,從這個(gè)角度來(lái)講,我們不是要隱藏一切“抽象-具體”的層級(jí)結(jié)構(gòu),而只是部分的,必要的。如上面的工廠就是隱藏不了了。

    不過(guò),也如我上面文章寫(xiě)的,隱藏不了具體工廠,其實(shí)沒(méi)有任何壞處。是可以接受的。畢竟我們對(duì)于具體產(chǎn)品的制定,在工廠模式中就轉(zhuǎn)換為對(duì)具體工廠的制定。

    -----------------
    再?gòu)?qiáng)調(diào),工廠模式的根本目的是“隱藏具體產(chǎn)品,只讓客戶端看到抽象產(chǎn)品”,你再品味一下,呵呵,我的話完了。  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2006-03-02 14:34 marco
    另外,對(duì)于你所的,為什么可以在設(shè)計(jì)中忽略工廠模式這個(gè)問(wèn)題。

    我想說(shuō)的是,假設(shè)你的類(lèi)設(shè)計(jì)中,存在大量的接口,抽象類(lèi)這樣的東西。而且類(lèi)與類(lèi)之間,也大部分是通過(guò)“這些東西“關(guān)聯(lián)起來(lái)的時(shí)候。

    正如你所說(shuō),是很難不去考慮,當(dāng)你真正要用的時(shí)候,到底上來(lái)的是那個(gè)具體類(lèi)。

    但是,我知道工廠模式肯定最后能幫我解決這個(gè)。所以,才暫時(shí)忽略,而不是不搞了。等我的設(shè)計(jì)都搞好了,我再把需要的工廠都補(bǔ)上去。

    對(duì)我來(lái)說(shuō),這個(gè)補(bǔ)充就是----仿佛是給”接口或抽象類(lèi)“制造一個(gè)new方法。

    所以,題目中的ignore不是說(shuō)這真的不管,而只是說(shuō)我相信一定可以搞定的意思。而在設(shè)計(jì)階段不用把它擺在主要位置而已。

    不知我有沒(méi)有給哥們您講清楚,再探討,再探討。  回復(fù)  更多評(píng)論
      

    # re: Java Web Application開(kāi)發(fā)日志之二--“Ignore how they were created”,工廠方法模式應(yīng)用 2007-05-26 13:44 goodstuff
    你講的深入淺出,非常棒,要繼續(xù)努力哦
    爭(zhēng)取做大陸的java的侯俊杰.  回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 黄+色+性+人免费| 亚洲日本乱码卡2卡3卡新区| 国产大片免费观看中文字幕| 日韩精品人妻系列无码专区免费| 又粗又长又爽又长黄免费视频| 亚洲小说图区综合在线| 亚洲高清无在码在线无弹窗| 中文字幕人成人乱码亚洲电影 | 国产免费观看青青草原网站| 91九色老熟女免费资源站| 成人免费区一区二区三区| 日本免费精品一区二区三区| 亚洲欧美日韩中文字幕在线一区| 亚洲熟妇av一区| 亚洲av无码不卡一区二区三区| 亚洲人成色7777在线观看不卡| 成人免费视频网址| 可以免费看黄视频的网站| 久久精品人成免费| 一级毛片aaaaaa免费看| a级大片免费观看| a毛片免费在线观看| 精品一区二区三区免费观看| 又大又硬又粗又黄的视频免费看| 美女又黄又免费的视频| 国产亚洲高清在线精品不卡| 亚洲AV无码国产一区二区三区| 亚洲欧美国产精品专区久久| 国产人成亚洲第一网站在线播放| 亚洲人成人网毛片在线播放| 亚洲av无码片在线观看| 亚洲1234区乱码| 亚洲 欧洲 日韩 综合在线| 国产 亚洲 中文在线 字幕| 亚洲人成无码网站在线观看| 亚洲最大无码中文字幕| 亚洲精品无码国产片| 亚洲爆乳无码精品AAA片蜜桃| 亚洲成AV人影片在线观看| 国产精品亚洲专区无码唯爱网| 精品一区二区三区无码免费直播|