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

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

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

    ivaneeo's blog

    自由的力量,自由的生活。

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

    #

    作法(Mechanics)

    首先是簡(jiǎn)單情況:

      • 找出只被賦值一次的臨時(shí)變量==>如果某個(gè)臨時(shí)變量被賦值超過一次,考慮使用Split Temporay Variable(128)將它分割成多個(gè)變量.
      • 將該臨時(shí)變量聲明為final.
      • 編譯.==>這可確保該臨時(shí)變量的確只被賦值一次.
      • 將[對(duì)臨時(shí)變量賦值]之語句的等號(hào)右側(cè)部分提煉到一個(gè)獨(dú)立函數(shù)中.
          • ==>首先將函數(shù)聲明為private.日后你可能會(huì)發(fā)現(xiàn)有更多class需要使用它,彼時(shí)你可輕易放松對(duì)它的保護(hù).
          • ==>確保提煉出來的函數(shù)無任何連帶影響(副作用),也就是說該函數(shù)并不修改任何對(duì)象內(nèi)容.如果它有連帶影響,就對(duì)它進(jìn)行Separate Query from Modifier(279).
      • 編譯,測(cè)試.
      • 在該臨時(shí)變量身上實(shí)施Inline Temp(119).

    我們常常使用臨時(shí)變量保存循環(huán)中的累加信息.在這種情況下,整個(gè)循環(huán)都可以被提煉為一個(gè)獨(dú)立函數(shù),這也使原本的函數(shù)可以少掉幾行擾人的循環(huán)代碼.有時(shí)候,你可能會(huì)用單一循環(huán)累加好幾個(gè)值.這種情況下你應(yīng)該針對(duì)每個(gè)累加值重復(fù)一遍循環(huán),這樣就可以將所有臨時(shí)變量都替換為查詢式(query).當(dāng)然,循環(huán)應(yīng)該很簡(jiǎn)單,復(fù)制這些代碼時(shí)才不會(huì)帶來危險(xiǎn).

    運(yùn)用此手法,呢可能會(huì)擔(dān)心性能問題.和其他性能問題一樣,我們現(xiàn)在不管它,因?yàn)樗邪司鸥静粫?huì)造成任何影響.如果性能真的出了問題,你也可以在優(yōu)化時(shí)期解決它.如果代碼組織良好,那么你往往能夠發(fā)現(xiàn)更有效的優(yōu)化法案;如果你沒有進(jìn)行重構(gòu),好的優(yōu)化法案就可能與你失之交臂.如果性能實(shí)在太糟糕,要把臨時(shí)變量放回去也是很容易的.

    posted @ 2005-08-25 15:04 ivaneeo 閱讀(228) | 評(píng)論 (0)編輯 收藏

    動(dòng)機(jī)(Motivation)
    臨時(shí)變量的問題在于:它們是暫時(shí)的,而且只能在所屬函數(shù)內(nèi)使用.由于臨時(shí)變量只有在所屬函數(shù)內(nèi)才可見,所以它們會(huì)驅(qū)使你寫出更長(zhǎng)的函數(shù),因?yàn)橹挥羞@樣你才能訪問到想要訪問的臨時(shí)變量.如果把臨時(shí)變量替換為一個(gè)查詢式(query method),那么同一個(gè)class中的所有函數(shù)都將可以獲得這份信息.這將帶給你極大幫助,使你能夠?yàn)檫@個(gè)class編寫更清晰的代碼.

    Replace Temp with Query(120)往往是你運(yùn)用Extract Method(110)之前必不可少的一個(gè)步驟.局部變量會(huì)使代碼難以被提煉,所以你應(yīng)該盡可能把它們替換為查詢式.

    這個(gè)重構(gòu)手法較為直率的情況就是:臨時(shí)變量只被賦值一次,或者賦值給臨時(shí)變量的表達(dá)式不受其他條件影響.其他情況比較棘手,但也有可能發(fā)生.你可能需要先運(yùn)用Split Temporary Variable(128)或Separate Query from Modifier(279)使情況變得簡(jiǎn)單一些,然后再替換臨時(shí)變量.如果你想替換的臨時(shí)變量是用來收集結(jié)果的(例如循環(huán)中的累加值),你就需要將某些程序邏輯(例如循環(huán))拷貝到查詢式(query method)去.
    posted @ 2005-08-25 14:43 ivaneeo 閱讀(266) | 評(píng)論 (0)編輯 收藏

    你的程序以一個(gè)臨時(shí)變量(temp)保存某一表達(dá)式的運(yùn)算結(jié)果.

    將這個(gè)表達(dá)式提煉到一個(gè)獨(dú)立函數(shù)中.將這個(gè)臨時(shí)變量的所有[被引用點(diǎn)]替換為[對(duì)新函數(shù)的調(diào)用].新函數(shù)可被其他函數(shù)使用.

    double basePrice = _quantity * _itemPrice;
    if(basePrice > 1000)
       return basePrice * 0.95;
    else
       return basePrice * 0.98;
                                        |   |
                                        |   |
                                       \    /
    if(basePrice() > 1000)
       return basePrice() * 0.95;
    else
       return base() * 0.98;
    ...
    double basePrice() {
       return _quantity * _itemPrice;
    }
    posted @ 2005-08-25 14:22 ivaneeo 閱讀(170) | 評(píng)論 (0)編輯 收藏

      • 作法(Mechanics)
      • 如果這個(gè)臨時(shí)變量并未被聲明為final,那就將它聲明為final,然后編譯.==>這可以檢查該臨時(shí)變量是否真的只被賦值一次.
      • 找到該臨時(shí)變量的所有引用點(diǎn),將它們替換為[為臨時(shí)變量賦值]之語句中的等號(hào)右側(cè)表達(dá)式.
      • 每次修改后,編譯并測(cè)試.
      • 修改完所有引用電之后,刪除該臨時(shí)變量的聲明式和賦值語句.
      • 編譯,測(cè)試.
    posted @ 2005-08-25 14:15 ivaneeo 閱讀(145) | 評(píng)論 (0)編輯 收藏

    動(dòng)機(jī)(Motivation)
    Inline Temp(119)多半是作為Replace Temp with Query(120)的一部分來使用,所以真正的動(dòng)機(jī)出現(xiàn)在后者那兒.唯一單獨(dú)使用Inline Temp(119)的情況是:你發(fā)現(xiàn)某個(gè)臨時(shí)變量被賦予某個(gè)函數(shù)調(diào)用的返回值.一般來說,這樣的臨時(shí)變量不會(huì)有任何危害,你可以放心地把它留在那兒.但如果這個(gè)臨時(shí)變量妨礙了其他的重構(gòu)手法--例如Extract Method(110),你就應(yīng)該就它inline化.

    posted @ 2005-08-25 13:53 ivaneeo 閱讀(184) | 評(píng)論 (0)編輯 收藏

    你有一個(gè)臨時(shí)變量,只被一個(gè)簡(jiǎn)單表達(dá)式賦值一次,而它妨礙了其他重構(gòu)方法.

    將所有對(duì)該變量的引用動(dòng)作,替換為對(duì)它賦值得那個(gè)表達(dá)式自身.

    double basePrice = anOrder.basePrice();
    return (basePrice > 1000);
                                  |   |
                                  |   |
                                 \    /
    return (anOrder.basePrice() > 1000);
    posted @ 2005-08-25 13:52 ivaneeo 閱讀(223) | 評(píng)論 (0)編輯 收藏

      • 作法(Mechanics)
      • 檢查函數(shù),確定它不具多態(tài)性(is not polymorphic).==>如果subclass繼承了這個(gè)函數(shù),就不要將此函數(shù)inline化,因?yàn)閟ubclass無法覆寫(override)一個(gè)根本不存在的函數(shù).
      • 找出這個(gè)函數(shù)的所有被調(diào)用點(diǎn).
      • 將這個(gè)函數(shù)的所有被調(diào)用點(diǎn)都替換為函數(shù)本體(代碼).
      • 編譯,測(cè)試.
      • 刪除該函數(shù)的定義.

    被我這樣一寫,Inline Method(117)似乎很簡(jiǎn)單.但情況往往并非如此.對(duì)于遞歸調(diào)用,多返回點(diǎn),inline至另一個(gè)對(duì)象中而該對(duì)象并無提供訪問函數(shù)(accessors)......,每一種情況我都可以寫上好幾頁.我之所以不寫這些特殊情況,原因很簡(jiǎn)單:如果你遇到了這樣的復(fù)雜情況,那么就不應(yīng)該使用這個(gè)重構(gòu)手法.

    posted @ 2005-08-24 17:28 ivaneeo 閱讀(194) | 評(píng)論 (0)編輯 收藏

    動(dòng)機(jī)(Motivation)
    有時(shí)候你會(huì)遇到某些函數(shù),其內(nèi)部代碼和函數(shù)名稱同樣清晰易讀.

    另一種需要使用Inline Method(117)的情況是:你手上有一群組織不甚合理的函數(shù).你可以將它們都inline到一個(gè)大型函數(shù)中,再?gòu)闹刑釤挸鼋M織合理的小型函數(shù).Kent Beck發(fā)現(xiàn),實(shí)施Replace Method with Method Object(135)之前先這么做,往往可以獲得不錯(cuò)的效果.你可以把你所要的函數(shù)(有著你要的行為)的所有調(diào)用對(duì)象的函數(shù)內(nèi)容都inline到method object(函數(shù)對(duì)象)中.比起既要移動(dòng)一個(gè)函數(shù),又要移動(dòng)它所調(diào)用的其他所有函數(shù),[將大型函數(shù)作為單一整體來移動(dòng)]會(huì)比較簡(jiǎn)單.

    如果別人使用了太多間接層,使得系統(tǒng)中的所有函數(shù)都似乎只是對(duì)另一個(gè)函數(shù)的簡(jiǎn)單委托(delegation),造成我在這些委托動(dòng)作之間暈頭轉(zhuǎn)向,那么我通常都會(huì)使用Inline Method(117).當(dāng)然,間接層有其價(jià)值,但不是所有間接層都有價(jià)值.試著使用inlining,我可以找出那些有用的間接層,同時(shí)將那些無用的間接層去除.
    posted @ 2005-08-24 17:12 ivaneeo 閱讀(189) | 評(píng)論 (0)編輯 收藏

    一個(gè)函數(shù),其本體(method body)應(yīng)該與其名稱(method name)同樣清楚易懂.

    在函數(shù)調(diào)用點(diǎn)插入函數(shù)本體,然后移除該函數(shù).

    int getRating() {
       return (moreThanFiveLateDeliveries()) ? 2 : 1;
    }
    boolean moreThanFiveLateDeliveries() {
       return _numberOfLateDeliveries > 5;
    }
                                         |   |
                                         |   |
                                        \    /

    int getRating() {
       return (_numberOfLateDeliveries > 5) ? 2 : 1;
    }
    posted @ 2005-08-24 16:55 ivaneeo 閱讀(182) | 評(píng)論 (0)編輯 收藏

    范例(Examples):對(duì)局部變量再賦值(Reassigning)
    如果被提煉碼對(duì)局部變量賦值,問題就變得復(fù)雜了.這里我們只討論臨時(shí)變量的問題.如果你發(fā)現(xiàn)源函數(shù)的參數(shù)被賦值,應(yīng)該馬上使用Remove Assignments to Parameters(131).

    被賦值的臨時(shí)變量也分兩種情況.較簡(jiǎn)單的情況是:這個(gè)變量只在被提煉碼區(qū)段中使用.果真如此,你可以將這個(gè)臨時(shí)變量的聲明式移到被提煉碼中,然后一起提煉出去.另一種情況是:被提煉碼之外的代碼也使用了這個(gè)變量.這又分為兩種情況:如果這個(gè)變量在被提煉碼之后未再被使用,你只需直接在目標(biāo)函數(shù)中修改它就可以了;如果被提煉碼之后的代碼還使用了這個(gè)變量,你就需要讓目標(biāo)函數(shù)返回該變量改變后的指.我以下列代碼說明這幾種不同情況:
    void printOwing() {
        Enumeration e = _orders.elements();
        double outstanding = 0.0;

       printBanner();

        // calculate outstanding
        while(e.hasMoreElements()) {
           Order each = (Order) e.nextElement();
           outstanding += each.getAmount();
        }

       printDetails(outstanding);
    }

    現(xiàn)在我把[計(jì)算]代碼提煉出來:

    void printOwing() {
       printBanner();
       double outstanding = getOutstanding();
       printDetails(outstanding);
    }

    double getOutstanding() {
           Enumeration e = _orders.elements();
           double outstanding = 0.0;

           while(e.hasMoreElements()) {
              Order each = (Order) e.nextElement();
              outstanding += each.getAmount();
           }
          return outstanding;
    }

    Enumeration變量e只在被提煉碼中用到,所以我可以將它整個(gè)搬到新函數(shù)中.double變量outstanding在被提煉碼內(nèi)外都被用到,所以我必須讓提煉出來的新函數(shù)返回它.編譯測(cè)試完成后,我就把傳值改名,遵循我的一貫命名原則:

    double getOutstanding() {
           Enumeration e = _orders.elements();
           double result = 0.0;

           while(e.hasMoreElements()) {
              Order each = (Order) e.nextElement();
              result += each.getAmount();
           }
          return result;
    }

    本例中的outstanding變量只是很單純地被初始化為一個(gè)明確初值,所以我可以只在新函數(shù)中對(duì)它初始化.如果代碼還對(duì)這個(gè)變量做了其他處理,我就必須將它的值作為參數(shù)傳給目標(biāo)函數(shù).對(duì)于這種變化,最初代碼可能是這樣:

    void printOwing(double previousAmount) {
        Enumeration e = _orders.elements();
        double outstanding = previousAmount * 1.2;

       printBanner();

        // calculate outstanding
        while(e.hasMoreElements()) {
           Order each = (Order) e.nextElement();
           outstanding += each.getAmount();
        }

       printDetails(outstanding);
    }

    提煉后的代碼可能是這樣:

    void printOwing(double previousAmount) {
       double outstanding = previousAmount * 1.2;

       printBanner();
       double outstanding = getOutstanding(outstanding);
       printDetails(outstanding);
    }
    double getOutstanding(double initialValue) {
           double result = initialValue;
           Enumeration e = _orders.elements();
           

           while(e.hasMoreElements()) {
              Order each = (Order) e.nextElement();
              result += each.getAmount();
           }
          return result;
    }
    編譯并測(cè)試后,我再將變量outstanding的初始化過程整理一下:
    void printOwing(double previousAmount) {
       printBanner();
       double outstanding = getOutstanding(previousAmount * 1.2);
       printDetails(outstanding);
    }

    這時(shí)候,你可能會(huì)問:[如果需要返回的變量不止一個(gè),又該怎么辦?]

    你有數(shù)種選擇.最好的選擇通常是:挑選另一塊代碼來提煉.我比較喜歡讓每個(gè)函數(shù)都只返回一個(gè)值,所以我會(huì)安排多個(gè)函數(shù),用以返回多個(gè)值.如果你使用的語言支持[輸出式參數(shù)](output parameters),你可以使用它們帶回多個(gè)回傳值.但我還是盡可能選擇單一返回值.

    臨時(shí)變量往往為數(shù)眾多,甚至?xí)固釤捁ぷ髋e步維艱.這種情況下,我會(huì)嘗試先運(yùn)用Replace Temp with Query(120)減少臨時(shí)變量.如果即使這么做了提煉依舊困難重重,我就會(huì)動(dòng)用Replace Method with Method Object(135),這個(gè)重構(gòu)手法不在乎代碼中有多少臨時(shí)變量,也不在乎你如何使用它們.

    posted @ 2005-08-24 16:14 ivaneeo 閱讀(219) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題
    共67頁: First 上一頁 48 49 50 51 52 53 54 55 56 下一頁 Last 
    主站蜘蛛池模板: 亚洲精品视频免费 | 波多野结衣免费视频观看| 亚洲成人免费网站| 免费人成在线观看网站品爱网| 中文字幕亚洲一区二区va在线| 成年大片免费高清在线看黄| 亚洲国产成人久久综合一区77 | 91青青国产在线观看免费| 亚洲熟妇无码久久精品| 亚欧在线精品免费观看一区| 亚洲国产精品久久丫| 毛色毛片免费观看| 亚洲AV无码国产精品永久一区| 免费在线不卡视频| 永久免费av无码不卡在线观看| 亚洲av纯肉无码精品动漫| 亚洲综合久久1区2区3区| 亚洲国产精品无码久久一线| 亚洲免费视频观看| 久久久久久国产精品免费免费男同| 亚洲春色另类小说| 亚洲图片在线观看| 成人性生交视频免费观看| 羞羞漫画页面免费入口欢迎你 | 色欲色欲天天天www亚洲伊| 亚洲另类自拍丝袜第1页| 亚洲精品综合一二三区在线| 亚洲精品无码MV在线观看| 在线精品免费视频| 91免费福利视频| 亚洲精品不卡视频| 337p日本欧洲亚洲大胆精品555588| 国产一级理论免费版| 午夜精品射精入后重之免费观看| 国产免费内射又粗又爽密桃视频 | 2022国内精品免费福利视频| 色噜噜的亚洲男人的天堂| 亚洲黄色一级毛片| 亚洲精品美女视频| 国产精品亚洲精品| 亚洲精品乱码久久久久久自慰|