將if else重構成可讀性較高的switch case

if else轉成switch case雖然不算重構,但轉成switch case之後,程式可讀性較高,且通常可以讓人聯想到下一步重構技巧,如Replace Type with State/Strategy,在PhpStorm 2016.1版中,新增了此項重構,非常實用。

Version


PhpStorm 2016.1

if else


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public function calculateTotalPrice() : int
{

$totalPrice = 0;

foreach ($this->orders as $order) {
$price = 0;

if ($order->getMovie()->getType() == 'Regular') {
$price += 100;
$price += ($order->getDays() - 7) * 10;
} elseif ($order->getMovie()->getType() == 'NewRelease') {
$price += 150;
$price += ($order->getDays() - 3) * 30;
}
elseif ($order->getMovie()->getType() == 'Children') {
$price += 40;
$price += ($order->getDays() - 7) * 10;
}
$totalPrice += $price;
}
return $totalPrice;
}

如以上程式,if else是根據$order->getMovie()->getType()判斷,這個可以用switch case改寫,可讀性會更高。1 1事實上這段程式是如何使用PhpStorm實現TDD、重構與偵錯?的範例,當時將if else轉成switch case是用手工做,因為當時的PhpStorm 10.0.3還沒有if else重構成switch case功能。

將游標放在if前面,按熱鍵⌥ + ↩ ,發現只有看到Flip if-else功能,不是可以轉成switch case嗎?

Extract Variable


因為if()內目前為method,目前PhpStorm還無法對此種寫法重構成switch case2 2理論上應該要可以,或許未來PhpStorm版本會支援。

必須先將此method使用Extract Variable提煉成變數。

選擇$order->getMovie()->getType(),按熱鍵⌃ + T,出現Refactor This選單,選擇Variable。

PhpStorm自動幫我們將變數取名為type,可自行修改。

Replace all occurences打勾,因為我們要將全部if()elseif()都使用變數取代。

if()elseif()都使用$type取代了。

switch case


在將游標放在if之前,按熱鍵⌥ + ↩,出現了Replace if with switch

程式從原本的if else重構成switch case了。

Conclusion


  • 目前PhpStorm要將if else重構成switch case時,有2個限制 :
    • if ()內必須為變數,所以可能需要先搭配Extract Variable。
    • 判斷式必須為==,不可以是===
  • 也可以將switch case轉成if else,方法完全一樣。