2018-02-09 可以降低圈復(fù)雜度的10種重構(gòu)技術(shù)

Composing Methods(重新組織你的函數(shù))

1.Extract Method(提煉函數(shù))

代碼段可被組織在一起并獨立出來

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

  // print banner
  System.out.println ("* * * * * * * * * * * * * * * * * * * * * * *");
  System.out.println ("Customer Owes ");
  System.out.println (" * * * * * * * * * * * * * * * * * * * * * * *");

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

  //print details
  System.out.println ("name:" +_name);
  System.out.println ("amount" + outstanding)
}

將這段代碼放進(jìn)一個獨立函數(shù)中傅寡,并讓函數(shù)名稱解釋該函數(shù)的用途

void printOwing(double previousAmount)
{
  printBanner();
  double  outstanding  =  getOutsta nding(previousAmount  *  1.2);
  printDetads(outstanding);
}

void printBanner0
{
   // print banner
.....
}

double getOutstanding(double initialValue)
{
  double result = initialValue;
  Enumeration e =  orders.elements();
  while (e.hasMoreElements())
  {
    Order each = (Order) e.nextElement();
     result += each.getAmount();
  }
  return result;
}

void printDetails (double outstanding)
 {
  //print details
...
}

2.Substitute Algorithm(替換你的算法)

把某個算法替換為另一個更清晰的算法

String foundPerson(String[] people)
{
  for (int i = 0; i < people.length; i++)
  {
      if (people[i].equals ("Don"))
       return "Don";
      if (people[i].equals ("John"))
       return "John";
      if (people[i].equals ("Kent"))
       return "Kent";
  }
  return "";
}

將函數(shù)本體替換為另一個算法

String foundPerson(String[] people)
{
   List candidates = Arrays.asList(new String[]{"Don", "John","Kent"});
   for (int i=0; i<people.length; i++)
      if (candidates.contains(people[i]))
         return people[i];
  return "";
}

Simplifying Conditional Expressions(簡化條件表達(dá)式)

3. Decompose Conditional(分解條件式)

你有一個復(fù)雜的條件語句,從if耘柱、else段落中分別提煉出獨立函數(shù)

if (date.before (SUMMER_START)  || date.after(SUMMER_END))
  charge = quantity * _winterRate  + winterServiceCharge;
else
  charge = quantity * _summerRate;

修改成

if (notSummer(date))
  charge = winterCharge(quantity);
else
  charge = summerCharge (quantity);

4.Consolidate Conditional Expression(合并條件式)

你有一系列條件判斷,都得到相同結(jié)果,將這些判斷合并為一個條件式矾飞,并將條件式提煉成為獨立函數(shù)枚冗。

double disabilityAmount()
{
   if (_seniority < 2) return 0;
   if (_monthsDisabled > 12) return 0;
   if (_isPartTime) return 0;
   // compute the disability amount
...
}

修改成

double disabilityAmount()
{
   if (isNotEligableForDisability()) return 0;
   // compute the disability amount
...
}

5.Consolidate Duplicate Conditional Fragments(合并重復(fù)的條件片斷)

在條件式的每個分支上有著相同的一段代碼, 將這段重復(fù)代碼搬移到條件式之外。

if (isSpeciaIDeal())
  {
     total = price * 0.95
     send();
  }
else
  {
     total = price* 0.98
     send();
  }

修改成

if (isSpeciaIDeal())
   total = price * 0.95
else
   total = price * 0.98
send();

6.Remove Control Flag(移除控制標(biāo)記)

在一系列布爾表達(dá)式種诞仓,某個變量帶有【控制標(biāo)記】的作用,以break和return取代控制標(biāo)記

void checkSecurity(String[] people) {
  boolean found = false;
  for (int i = 0; i < people.length; i++) {
      if (l found) {
         if (people[i].equals ("Don")){
          sendAlert();
           found = true;
       }
         if (people[i].equals ("John")){
           sendAlert();
             found = true;
       }
     }
  }
}

變成

void checkSecurity(String[] people) {
  for (int i = 0; i < people.length; i++) {
      if (people[i].equals ("Don")){
       sendAlert();
       break;
     }
      if (people[i].equals ("John")){
       sendAlert();
       break;
     }
  }
}

Making Method Calls Simpler(簡化函數(shù)調(diào)用)

7.Separate Query from Modifier(將查詢函數(shù)和修改函數(shù)分離)

某個函數(shù)既返回對象狀態(tài)值枉侧,又修改對象狀態(tài)。 建立兩個不同的函數(shù)狂芋, 其中一個負(fù)責(zé)查詢榨馁,另一個負(fù)責(zé)修改

Customer::getTotalOutstandingAndSetReadyForSummaries(...)
{
...
}

分成兩個函數(shù)

Customer::getTotalOutstanding(...)
{
...
}
Customer::SetReadyForSummaries(...)
{
...
}

8.Parameterize Method(令函數(shù)攜帶參數(shù))

若干函數(shù)做了類似的工作,但在函數(shù)本體中卻包含了不同的值帜矾。建立單一函數(shù)翼虫,以參數(shù)表達(dá)那些不同的值

Dollars baseCharge0
 {
   double result = Math.min(lastUsage(),l00) * 0.03;
   if (lastUsage() > 100) {
     result += (Math.min (lastUsage(),200) - 100) * 0.05;
  };
   if (lastUsage() > 200) {
     result += (lastUsage() - 200)*0.07;
  };
  return new Dollars (result);
}

修改成

Dollars baseCharge()
{
   double result = usagelnRange(0, 100)* 0.03;
   result += usagelnRange (100,200) * 0.05;
   result += usagelnRange (200, Integer.MAX  VALUE) * 0.07
  return new Dollars (result);
}
int usagelnRange(int start, int end)
{
   if (lastUsage() > start)
     return Math.min(lastUsage(),end) -start
   else
     return 0;
}

9.Replace Parameter with Explicit Methods(以明確函數(shù)取代參數(shù))

函數(shù)實現(xiàn)完全取決于參數(shù)值而采取不同反應(yīng)屑柔,針對該參數(shù)的每一個可能值,建立一個獨立函數(shù)

void setValue (String name, int value)
{
   if (name.equals("height"))
      _height = value;
   if (name.equals("width"))
      _width = value;
  Assert.shouldNeverReachHere();
}

改成

void setHeight(int arg)
{
  _height = arg;
}
void setWidth (int arg)
{
  _width = arg;
}

10.Replace Conditional with Polymorphism(以多態(tài)取代條件式)

你手上有個條件式珍剑,它根據(jù)對象類型的不同而選擇不同的行為掸宛。那么,將整個條件式的每個分支放進(jìn)子類的重載方法中招拙, 然后將原始函數(shù)聲明為抽象方法

double getSpeed()
{
   switch (_type) {
     case EUROPEAN:
       return getBaseSpeed();
     case AFRICAN:
      return getBaseSpeed() - getLoadFactor() *_numberOfCoconuts;
     case NORWEGIAN_BLUE:
       return (isNailed)  ? 0 : getBaseSpeed(_voltage);
    }
  throw new RuntimeException ("Should be unreachable");
}

修改成


image.png

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末唧瘾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子别凤,更是在濱河造成了極大的恐慌饰序,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件规哪,死亡現(xiàn)場離奇詭異求豫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诉稍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門蝠嘉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人杯巨,你說我怎么就攤上這事蚤告。” “怎么了服爷?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵罩缴,是天一觀的道長。 經(jīng)常有香客問我层扶,道長箫章,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任镜会,我火速辦了婚禮檬寂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘戳表。我一直安慰自己桶至,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布匾旭。 她就那樣靜靜地躺著镣屹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪价涝。 梳的紋絲不亂的頭發(fā)上女蜈,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼伪窖。 笑死逸寓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的覆山。 我是一名探鬼主播竹伸,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼簇宽!你這毒婦竟也來了勋篓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤魏割,失蹤者是張志新(化名)和其女友劉穎譬嚣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體见妒,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年甸陌,在試婚紗的時候發(fā)現(xiàn)自己被綠了须揣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡钱豁,死狀恐怖耻卡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情牲尺,我是刑警寧澤卵酪,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站谤碳,受9級特大地震影響溃卡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜒简,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一瘸羡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧搓茬,春花似錦犹赖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锡凝,卻和暖如春粘昨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工雾棺, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留膊夹,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓捌浩,卻偏偏與公主長得像放刨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子尸饺,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一個軟件總是為解決某種特定的需求而產(chǎn)生进统,時代在發(fā)展,客戶的業(yè)務(wù)也在發(fā)生變化浪听。有的需求相對穩(wěn)定一些螟碎,有的需求變化的比...
    Rance935閱讀 7,885評論 0 9
  • 閱讀《重構(gòu)》的筆記獻(xiàn)上掉分。 重構(gòu)的定義 重構(gòu)是在不改變軟件可觀察行為的前提下改善其內(nèi)部結(jié)構(gòu)。 重構(gòu)的節(jié)奏 以微小的步...
    陳宇明閱讀 11,639評論 13 64
  • 一克伊,重構(gòu)酥郭,第一個案例 這一章作者先用一個影片出租程序的案例,來演示重構(gòu)的過程 每個Customer顧客可以租多部M...
    高稷閱讀 10,819評論 1 19
  • 前些天,逛超市看到里脊搞活動犁跪,又很鮮嫩椿息,便買了些來。昨日去玉淵潭坷衍,看到錦州豆皮寝优,也買了些,今日便給波爸和昊寶做了京...
    懶媽一枚閱讀 780評論 2 4
  • 這本書是核聚推薦的枫耳,核聚是我在寫作群里一個男生—歡喜倡勇,文章中經(jīng)常提及的人物。大概是一個北大博士嘉涌,沒有運動員經(jīng)驗的他...
    春天的約會閱讀 360評論 0 3