ivaneeo's blog

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

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks
          范例(Examples)
          我用一個表示[帳戶]的account class來說明這項重構(gòu):
          class Account...
              double overdraftCharge() {   //透支金計費(fèi),它和其他class的關(guān)系似乎比較密切。
                 if(_type.isPremium()) {
                    double result = 10;
                    if(_daysOverdrawn > 7)
                       result += (_daysOverdrawn -7) * 0.85;
                    return result;
                 }
                 else return _daysOverdrawn * 1.75;
              }
              double bankCharge() {
                 double result = 4.5;
                 if(_daysOverdrawn > 0) result += overdraftCh你arge();
                 return result;
              }
              private AccountType _type;
              private int _daysOverdrawn;

          假設(shè)有數(shù)種新帳戶,每一種都有自己的[透支金計費(fèi)規(guī)則]。所以我希望將overdraftCharge()搬移到AccountType class去。

          第一步要做的是:觀察被overdraftCharge()使用的每一特性(features),考慮是否值得將它們與overdraftCharge()一起移動。此例之中我需要讓_daysOverdrawn值域留在Account class,因為其值會隨不同種類的帳戶而變化。然后,我將overdraftCharge()函數(shù)碼拷貝到AccountType中,并做相應(yīng)調(diào)整。
          class AccountType...
              double overdraftCharge(int daysOverdrawn) {
                 if(isPremium()) {
                    double result = 10;
                    if(daysOverdrawn >7)
                       result += (daysOverdrawn - 7) * 0.85;
                    return result;
                  }
                 else return daysOverdrawn * 1.75;
              }
          在這個例子中,[調(diào)整]的意思是:(1)對于[使用AccountType特性]的語句,去掉──type;(2)想辦法得到依舊需要的Account class特性。當(dāng)我需要使用source class特性,我有四種選擇:(1)將這個特性也移到target class;(2)建立或使用一個從target class到source的引用(指涉)關(guān)系;(3)將source object當(dāng)作參數(shù)傳給target method;(4)如果所需特性是個變量,將它當(dāng)作參數(shù)傳給target method。

          本例中我將_daysOverdrawn變量作為參數(shù)傳給target method(上述(4))。

          調(diào)整target method使之通過編譯,而后我就可以將source method的函數(shù)本體替換為一個簡單的委托動作(delegation),然后編譯并測試:
              class Account...
                 double overdraftCharge() {
                    return _type.overdraftCharge(_daysOverdrawn);
                 }
          我可以保留代碼如今的樣子,也可以刪除source method。如果決定刪除,就得找出source method的所有調(diào)用者,并將這些調(diào)用重新定向,改調(diào)用Account的bankCharge():
          bankCharge():
              class Account...
                 double bankCharge() {
                    double result = 4.5;
                    if(_daysOverdrawn > 0)
                       result += _type.overdraftCharge(_daysOverdrawn);
                    return result;
                  }
          所有調(diào)用點都修改完畢后,我就可以刪除source method在Account中的聲明了。我可以在每次刪除之后編譯并測試,也可以一次性批量完成。如果被搬移的函數(shù)不是private,我還需要檢查其 他classes是否使用了這個函數(shù)。在強(qiáng)型(strongly typed)語言中,刪除source method聲明式后,編譯器幫我發(fā)現(xiàn)任何遺漏。

          此例之中被移函數(shù)只取用(指涉)一個值域,所以我只需將這個值域作為參數(shù)傳給target method就行了。如果被移函數(shù)調(diào)用了Account中的另一個函數(shù),我就不能這么簡單地處理。這種情況下我必須將source object傳遞給target method:
          class AccountType...
              double overdraftCharge(Account account) {
                 if(isPremium()) {
                    double result = 10;
                    if(account.getDaysOverdrawn() >7)
                       result += (account.getdaysOverdrawn() - 7) * 0.85;
                    return result;
                  }
                 else return daysOverdrawn * 1.75;
              }
          如果我需要source class的多個特性,那么我也會將source object傳遞給target method。不過如果target method需要太多source class特性,就得進(jìn)一步重構(gòu)。通常這種情況下我會分解target method,并將其中一部分移回source class。
          posted on 2005-08-30 11:08 ivaneeo 閱讀(225) 評論(0)  編輯  收藏 所屬分類: refactoring-從地獄中重生
          主站蜘蛛池模板: 南郑县| 红原县| 九龙坡区| 福州市| 贵阳市| 南丰县| 东平县| 汕尾市| 吉木萨尔县| 马龙县| 盐源县| 杂多县| 盐山县| 东光县| 西丰县| 扬州市| 屯留县| 深州市| 蒙自县| 南岸区| 进贤县| 侯马市| 什邡市| 嘉祥县| 梅河口市| 观塘区| 南丹县| 高邮市| 延长县| 都昌县| 六枝特区| 漳平市| 黄龙县| 昌图县| 婺源县| 泰宁县| 镇平县| 惠东县| 沙坪坝区| 叶城县| 富蕴县|