PhpStorm無法直接實現此重構,需搭配一些技巧

若我們直接對參數做修改,會使得將來的Extract Method難度更高,因此在執行Extract Method之前,我們常常會執行Move Assignment to Parameters,先將參數指定給暫存變數,然後將後續的程式全部改成修改此暫存變數

Version


PHP 7.0.0
PhpStorm 10.0.3

定義


在程式中對參數的值進行修改 => 以一個暫時變數取代該參數

1
2
3
4
5
public function discount(int $inputVal, int $quantity, int $yearToDate) : int {
if ($inputVal > 50) {
$inputVal -= 2;
}
}

重構成

1
2
3
4
5
6
7
public function discount(int $inputVal, int $quantity, int $yearToDate) : int {
$result = $inputVal;

if ($inputVal > 50) {
$result -= 2;
}
}

目的


  1. 提升程式的可讀性,參數只用來代表傳進來的資料
  2. 不要混用pass by valuepass by reference的資料處理方式。
  3. 保持參數不變,方便Extract Method進行。

重構前的程式碼


重構 : 改善既有程式的設計 (二版)的範例程式,改寫成PHP後的程式碼如下 : 1 1GitHub Commit : 重構前的程式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class ShoppingCart
{

/**
* @param int $inputVal
* @param int $quantity
* @param int $yearToDate
* @return int
*/

public function discount(int $inputVal, int $quantity, int $yearToDate) : int
{

if ($inputVal > 50) {
$inputVal -= 2;
}

if ($quantity > 100) {
$inputVal -= 1;
}

if ($yearToDate > 10000) {
$inputVal -= 4;
}

return $inputVal;
}
}

我們看到$inputVal為參數,但在12行、16行、20行卻對$inputVal去做修改。

因此我們想使用Remove Assignments to Parameters$inputVal做重構。

Move Assignments to Parameters


新增暫時變數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
namespace app;

class ShoppingCart
{

/**
* @param int $inputVal
* @param int $quantity
* @param int $yearToDate
* @return int
*/

public function discount(int $inputVal, int $quantity, int $yearToDate) : int
{

$result = $inputVal;

if ($inputVal > 50) {
$inputVal -= 2;
}

if ($quantity > 100) {
$inputVal -= 1;
}

if ($yearToDate > 10000) {
$inputVal -= 4;
}

return $inputVal;
}
}

14行

1
$result = $inputVal;

為了不讓程式直接修改參數$inputVal,我們新增了暫時變數$result2 2GitHub Commit : 新增臨時變數

修改暫存變數

我們知道20行、24行、28行與31行的$inputVal都要改成$result,很可惜目前PhpStorm的重構,並無法直接支援Remove Assignments to Parameters3 3若直接根據$inputVal執行Rename,會將所有的$inputVal都改成$result,可惜這也不是我們所要的。

以下介紹兩種方法 :

手動重構

按住⌥,將所有你想重構的變數後面用滑鼠點一下,如上圖20行、24行、28行與31行之後都出現了游標閃爍。

之後按⌦,會發現這4個$inputVal已經可連動刪除了。

可一次只將4個$inputVal改成$result4 4GitHub Commit : 修改暫存變數

半自動重構

若要重構的變數很多,可能無法立刻判斷要重構哪些變數,可以由PhpStorm幫我們搜尋,我們再判斷此變數是否必須重構。

用滑鼠點一下第一個與預期重構變數同名的變數,可以是要重構的變數,也可以是不要重構的變數。

若此變數正是欲重構的變數,則按⌃ + G,表示選擇了此變數。

若此變數不是欲重構的變數,則按⌘ + G,表示繼續搜尋與此變數同名的變數。

因為第一個$inputVal並非要重構的變數,因此按⌘ + G繼續搜尋下一個變數。

$inputVal也不是我們要重構的變數,因此按⌘ + G繼續搜尋下一個變數。

$inputVal為我們要重構的變數,因此按⌃ + G選擇了此變數。

按⌃ + G之後,預設會一併選擇下一個變數,若此變數不是你要重構的變數,一樣按⌘ + G跳過,若要選擇此變數則按⌃ + G選擇了此變數。

$inputVal為我們要重構的變數,因此按⌃ + G選擇了此變數。

$inputVal為我們要重構的變數,因此按⌃ + G選擇了此變數。

如此我們就選擇了4個我們要重構的變數。

一併將4個$inputVal都改成$result

Conclusion


  • PhpStorm雖然已經內建很多重構功能,不過有些重構還是無法直接完成,需靠一些技巧。
  • ⌥ + 滑鼠點擊,可手動選擇要重構的變數。
  • ⌘ + G與⌃ + G,可半自動選擇要重構的變數。

Sample Code


完整的範例可以在我的GitHub上找到。