針對 Method 的 Signature 加以重構

Rider 相當於 IntelliJ + Resharper,除了保有 IntelliJ 平台的特色外,還包含 Resharper 強悍的功能,本文將討論其 Refactoring 中的 Change Signature。

Version


macOS High Sierra 10.13.3
Rider 2018.1

Change Signature


實務上常在通過單元測試後,在重構階段才發現 method 的 parameter 需要重構,此時就該使用 Change Signature。

  • 重構 method 名稱:Method、Property、Indexer
  • 重構 method 回傳型別:Method、Property
  • 重構 parameter 名稱與型別:Method、Constructor、Indexer
  • 新增或刪除 parameter:Method、Constructor、Indexer
  • 重構 parameter 順序:Method、Constructor、Indexer

重構 Signature 並修改 Client


Calculator.cs

1
2
3
4
5
6
7
8
9
10
namespace ClassLibrary
{
public class Calculator
{
public int Add(int x, int y)
{

return x + y;
}
}
}

Program.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using ClassLibrary;

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{

var calculator = new Calculator();
var result = calculator.Add(1, 1);

Console.WriteLine("{0}", result);
}
}
}

欲將 Calculator.Add() 加以 Change Signature。

sig000

  1. 將游標放到 Add()
  2. 按熱鍵:⌃ + T,選擇 Change Signature

sig001

  1. 將 method 名稱重構成 Add3
  2. 增加 parameter int x
  3. 對原本呼叫的 function 選擇直接 Modify (稍後會介紹 Delegate via overloading method)
  4. Next 下一步

sig002

對於新增的 parameter,Rider 提供 4 種重構方式

  1. Leave code non-compatible, I'll correct calls my selft:也就是 Rider 不做任何修改
  2. Use 0:Rider 會對新的參數傳入 0
  3. Resolve with call tree:Rider 會對每個呼叫的 method 停下來,讓我們決定該如何修改 (稍後會介紹)
  4. Use the following value:統一給定指定值傳入

在此選擇 Use 0

sig003

  1. Rider 替我們將 method 名稱改成 Add3()
  2. Rider 替我們增加了 parameter int z

sig004

  1. Client 也改成 Add3
  2. Argument 多傳了 0

重構 Signature 但不修改 Client


sig005

  1. 選擇 Delegate via overloading method,將以 Overloading 方式重構

sig002

對於 client,一樣有 4 種重構方式。

sig006

  1. 原本的 Add() 重構成 Add3(),也增加了 parameter int z
  2. 另外新增一個 Add() 呼叫 Add3(),如此可在不修改 Client 的情況下,改變 signature

如 class library 已經正式發佈,有其他的 client 使用中,這種重構方式可使的 client 不用修改程式碼,也能達到 Change Signature 的目的

直接修改 Client 的 Argument


sig007

  1. 直接在 client 新增 argument 2
  2. 按熱鍵 ⌥ + ↩,顯示了多種重構方式,甚至可以新增 Overloading Method

sig008

  1. Rider 幫我們增加了新 parameter int i

根據 Call Tree 逐步修改 Client


Calculator.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace ClassLibrary
{
public class Calculator
{
public int Add(int x, int y)
{

return x + y;
}

public int Multiply(int x, int y)
{

return x * y;
}

public int Calculate(int x, int y, int z)
{

return Multiply(Add(x, y), z);
}
}
}

新增 Multiply()Calculate()

Program.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using ClassLibrary;

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{

var calculator = new Calculator();
var result = calculator.Calculate(1, 2, 3);

Console.WriteLine("{0}", result);
}
}
}

Client 改呼叫 Calculate()

sig009

一樣針對 Add() 加以重構。

sig001

一樣重構 method name 與增加 parameter。

sig010

  1. 選擇 Resolve with call tree

sig011

  1. Rider 會逐一根據 call tree 一步一步重構,首先遇到呼叫 Add3() 之處,會詢問你該如何重構,內建提供多種方法,選擇 Create field _z in type Calculator

sig012

  1. Rider 自動幫我們加上 field 與 Constructor

sig013

既然 Calculator 新增了 constructor,接下來就是針對 constructor 加以重構。

  1. 針對 constructor 也提供了眾多重構方式,選擇 User edit

sig014

  1. 自行在 constructor 輸入 4

Conclusion


  • Rider 針對 Change Signature 提供多種重構方式,甚至還可以根據 call tree,一步一步提供客製化的重構

Sample Code


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

Reference


JetBrains Rider, Change Signature refactoring

2018-04-22