中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

軟件開發(fā)-重構(gòu)

  重構(gòu)是對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變軟件之可察性前提下,提高其可理解性,降低其修改成本。關(guān)于重構(gòu)的至理明言如下:

  • 任何一個(gè)傻瓜都能寫出計(jì)算器可以理解的代碼,唯有寫出人類容易理解的代碼,才是優(yōu)秀的程序員;
  • 事不過(guò)三,三則重構(gòu);
  • 當(dāng)你接獲bug提報(bào),請(qǐng)先撰寫一個(gè)單元測(cè)試來(lái)揭發(fā)這個(gè)bug;
  • 當(dāng)你感覺(jué)需要撰寫注釋,請(qǐng)先嘗試重構(gòu),試著讓所有的注釋變得多余;
  • 當(dāng)你發(fā)現(xiàn)自己需要為程序增加一個(gè)特性,而代碼結(jié)構(gòu)使你無(wú)法方便的這樣做,就先重構(gòu)那個(gè)程序;
  • 重構(gòu)之前,必須建立一套可靠的測(cè)試機(jī)制;
  • 寫軟件就像種樹,優(yōu)秀的程序員挖成小坑后隨及填好,繼續(xù)挖下一個(gè),只會(huì)產(chǎn)生一系列小坑,不會(huì)有大坑,菜鳥則不會(huì)意識(shí)到所挖的坑正在變大,還是不停的挖,直到自己掉進(jìn)大坑,爬不出來(lái),陷入無(wú)盡的痛苦深淵;
  • 開發(fā)時(shí)間越長(zhǎng),越能體會(huì)垃圾代碼的痛苦,卻不知道如何改進(jìn);
  • Kent Beck:我不是一個(gè)偉大的程序員,我只是個(gè)有著一些優(yōu)秀習(xí)慣的好程序員而已;

  變量(Variable)

  不要定義一個(gè)臨時(shí)變量多次重復(fù)使用,臨時(shí)變量定義仍然應(yīng)該可以自解釋,從變量名稱能夠很好的理解變量的含義和作用。在定義一個(gè)臨時(shí)變量后需要有一段業(yè)務(wù)邏輯才能夠完成對(duì)臨時(shí)變量的賦值的時(shí)候,可以考慮將這段邏輯抽取到一個(gè)獨(dú)立的方法。

    doublegetPrice(){

       int basePrice = _quantity* _itemPrice;
       double discountFactor;
       if (basePrice > 1000) discountFactor = 0.95;
       else discountFactor = 0.98;
       return basePrice * discountFactor;
    }

重構(gòu)為:

   double getPrice(){
       return basePrice()* discountFactor();
   }

   private int basePrice(){
       return _quantity* _itemPrice;
   }

   private double discountFactor(){
       if (basePrice()> 1000) return0.95;
       else return 0.98;
   }

當(dāng)遇到復(fù)雜的表達(dá)式的時(shí)候,需要引入解釋變量,因?yàn)閺?fù)雜的表達(dá)式很難進(jìn)行自解釋。

if ((platform.toUpperCase().indexOf("MAC")> -1)&&
   (browser.toUpperCase().indexOf("IE")> -1)&&
    wasInitialized()&& resize> 0 )
{
     // do something
}

重構(gòu)為:

final booleanisMacOs    = platform.toUpperCase().indexOf("MAC")>-1;
final boolean isIEBrowser =browser.toUpperCase().indexOf("IE") > -1;
final booleanwasResized  = resize >0;

if (isMacOs&& isIEBrowser&& wasInitialized()&& wasResized){
   // do something
}

  減少對(duì)全局變量的使用,第一個(gè)是全局變量的生命周期很難控制,資源本身無(wú)法得到很快的釋放,其二是過(guò)多使用全局變量導(dǎo)致在調(diào)用方法的時(shí)候很難完全清楚方法說(shuō)需要的入口數(shù)據(jù)信息,其三,多處都可以對(duì)全局變量賦值,我們很難立刻定位到當(dāng)前全局變量的值來(lái)源自哪里?

  分解方法(Extract Method)

  一個(gè)較大的方法往往也會(huì)分為多個(gè)小的段落,step1,step2,step3,在每一個(gè)步驟都會(huì)考慮添加注釋說(shuō)明。而這些相對(duì)較為獨(dú)立的步驟就可以分解為不同的方法,在分解后方法名可以自解釋方法的功能而不再需要額外的注釋。在一個(gè)類里面如果方法里面有一段代碼在多個(gè)方法中重復(fù)出現(xiàn),需要抽取該類的公用方法。在多個(gè)不同的類中有一段代碼重復(fù)出現(xiàn),需要考慮將公用代碼放到公用類中形成公用方法。

  方法名需要很好的自解釋方法的功能,方法的返回盡量單一,方法的入口參數(shù)太多的時(shí)候應(yīng)該考慮使用集合,結(jié)構(gòu)或數(shù)據(jù)對(duì)象進(jìn)行參數(shù)的傳遞。參數(shù)的傳遞可能出傳遞的是引用,但不要去修改入口參數(shù)的值。

  不要因?yàn)橐粋€(gè)方法里面只有一行,兩行很短而不考慮去分解,分解的時(shí)候更多的是考慮代碼的自解釋性。代碼本身不是解釋的技術(shù)實(shí)現(xiàn)機(jī)制,而是解釋的業(yè)務(wù)規(guī)則和需求。如果代碼不是解釋的業(yè)務(wù)規(guī)則和需求,那么其它人員就很難快速理解。

  引入方法對(duì)象來(lái)取代方法,當(dāng)發(fā)現(xiàn)一個(gè)方法只用到該類里面的幾個(gè)關(guān)鍵屬性,方法和類里面其它的方法交互很少,輸出單一。由于該方法和這幾個(gè)屬性內(nèi)聚性很強(qiáng)而和該類其它部分松耦合,因此可以考慮將方法和這部分屬性移出形成一個(gè)單獨(dú)的方法對(duì)象。

  移動(dòng)方法,類的職責(zé)要單一,一個(gè)類的方法更多用到了別的類的屬性,這個(gè)方法可能更適合定義在那個(gè)類中。

class Account...
   private AccountType_type;
   private int_daysOverdrawn;
   
   double overdraftCharge(){
      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 +=overdraftCharge();
      return result;
   }

  重構(gòu)為:

classAccount...
  private AccountType _type;
  private int _daysOverdrawn;   
  double overdraftCharge(){
      return _type.overdraftCharge(_daysOverdrawn);
  }

  double bankCharge(){
      double result = 4.5;
      if (_daysOverdrawn > 0)
          result += _type.overdraftCharge(_daysOverdrawn);
      return result;
  }

classAccountType...
  double overdraftCharge(Account account){
      if (isPremium()){
          double result = 10;
          if (account.getDaysOverdrawn()> 7)
             result += (account.getDaysOverdrawn()- 7)* 0.85;
          return result;
      }
      else return account.getDaysOverdrawn()* 1.75;
  }

  分解類(Extract Class)

  類的職責(zé)的劃分不容易在初次設(shè)計(jì)時(shí)就準(zhǔn)確把握,所以在編碼時(shí)重構(gòu)是必要的。職責(zé)定位不清!——典型特征是擁有太多的成員變量;而在這里面最重要的就是職責(zé)要單一,屬性和方法是否合適的類中。如果不是就需要考慮分解或合并,擴(kuò)展類的功能,或者抽象相應(yīng)的接口。面向?qū)ο蟮脑O(shè)計(jì)原則如下:

1.單一職責(zé)原則(SRP)-就一個(gè)類而言,應(yīng)該僅有一個(gè)引起它變化的原因

  類的職責(zé)要單一,類里面的方法只做類的職責(zé)范圍里面的事情。MVC即是一種粗粒度的職責(zé)話費(fèi),模型類重點(diǎn)是提供數(shù)據(jù),控制類重點(diǎn)是處理業(yè)務(wù)邏輯,而V視圖類則是關(guān)注數(shù)據(jù)獲取后的呈現(xiàn)。

  數(shù)據(jù)和數(shù)據(jù)操作可以考慮分解,如形成專門的DTO數(shù)據(jù)傳輸對(duì)象類。界面類和界面數(shù)據(jù)提供類也可以考慮分離,如形成專門的Facade層專門負(fù)責(zé)數(shù)據(jù)的準(zhǔn)備和形成。界面層不應(yīng)該有太多的數(shù)據(jù)處理操作。

  當(dāng)發(fā)現(xiàn)一個(gè)大的類里面的屬性和方法存在明細(xì)的分組特性的時(shí)候,而且分組直接松散耦合,需要考慮分解為多個(gè)類。

  引入方法對(duì)象來(lái)取代方法,當(dāng)發(fā)現(xiàn)一個(gè)方法只用到該類里面的幾個(gè)關(guān)鍵屬性,方法和類里面其它的方法交互很少,輸出單一。由于該方法和這幾個(gè)屬性內(nèi)聚性很強(qiáng)而和該類其它部分松耦合,因此可以考慮將方法和這部分屬性移出形成一個(gè)單獨(dú)的方法對(duì)象。

  胖接口也是違反職責(zé)單一,胖接口會(huì)導(dǎo)致所有實(shí)現(xiàn)接口的類都Override所有的接口方法,而有些接口方法往往是子類并不需要的。因此對(duì)于胖接口仍然要從職責(zé)的角度對(duì)接口進(jìn)行拆分。

2.開放——封閉原則(OCP)-對(duì)擴(kuò)展開放,對(duì)修改封閉

  當(dāng)發(fā)生變化時(shí),只需要添加新的代碼,而不必改動(dòng)已經(jīng)正常運(yùn)行的代碼:軟件人的夢(mèng)想!而要達(dá)到這個(gè)目的,關(guān)鍵是要能夠較為準(zhǔn)確的預(yù)測(cè)業(yè)務(wù)變化會(huì)導(dǎo)致的可能會(huì)發(fā)送變化的模塊或代碼。

3.Liskov替換原則(LSP)

  子類型必須能夠替換掉他們的基類型。正是子類型的可替換性,才使得使用基類類型的軟件無(wú)須修改就可以擴(kuò)展。案例參考正方形駁論。矩形的合理假設(shè):長(zhǎng)、寬可以獨(dú)立變化;而正方形的合理假設(shè):長(zhǎng)、寬始終相等。因此正方形并不能從矩形繼承。

4.依賴倒置原則(DIP)-高層模塊不應(yīng)該依賴于低層模塊;抽象不應(yīng)該依賴于細(xì)節(jié)。

軟件開發(fā)-重構(gòu)

  依賴倒置原則的重點(diǎn)是高層模塊類不要去依賴底層模塊的類,而應(yīng)該去依賴接口,特別是當(dāng)我們預(yù)見到底層模塊的類本身可能會(huì)擴(kuò)展和變化的時(shí)候。這樣在變化的時(shí)候最大的好處就是高層類和接口不用變化。

  類是否考慮抽象為接口,一方面是根據(jù)LSP原則進(jìn)行重構(gòu),一方面是需要觀察我們建立的類,是否有多個(gè)類本身存在相同的行為或方法,如果存在則需要考慮抽象接口。

it知識(shí)庫(kù)軟件開發(fā)-重構(gòu),轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 日日操夜夜摸 | 国产一级电影网 | 毛片在线视频 | 久草视频在线播放 | 色婷婷精品国产一区二区三区 | 成人精品国产一区二区4080 | 午夜三级网站 | 久久久www成人免费无遮挡大片 | 精品一二区 | 三级av在线| 黑人巨大精品欧美一区二区一视频 | 国产在线观看av | 亚洲日韩中文字幕一区 | av片免费观看 | cao视频 | 国产精品视频久久 | 精品一区二区三区四区五区 | 国产午夜精品视频 | 午夜爱爱网| 精品一区二区三 | 一级毛片免费 | 亚洲天堂免费在线 | 中文字幕在线视频观看 | 午夜精品久久久久久久久久久久久 | 欧美日韩不卡在线 | 日韩欧美精品在线播放 | 精品国产91亚洲一区二区三区www | 精品国产乱码久久久久久蜜退臀 | 成年免费大片黄在线观看一级 | 美女福利视频网站 | 久久久久国产精品一区 | 农村真人裸体丰满少妇毛片 | 日韩aⅴ视频 | 午夜国产一级 | 欧洲妇女成人淫片aaa视频 | 国产视频1区 | 日韩欧美国产精品一区二区 | 亚洲在线免费 | 夜夜骑首页 | 精品久久香蕉国产线看观看亚洲 | 欧美日本韩国一区二区三区 |