前言
近期上了大神的課,學了滿多重構技巧,還在目瞪口呆慢慢消化吸收中,而手邊又剛好有跟朋友借來的書,決定紀錄一下。
本文
以前常遇到寫了一個 Class 裡面有很多方法,一眼看下去很難理解內容在做甚麼;而在考慮要拆分的時候就可以使用 Extract Class 這個技巧,在一整個 Class 內可以試著尋找可以歸類成一塊的部分,慢慢地進行拆分。
首先按照書上介紹我們先建立 Person 這個類別。
public class Person
{
private string _name;
private string _officeAreaCode;
private string _officeNumber;
public string GetName()
{
return this._name;
}
public void SetName(string input)
{
this._name = input;
}
public string GetOfficeAreaCode()
{
return this._officeAreaCode;
}
public void SetOfficeAreaCode(string input)
{
this._officeAreaCode = input;
}
public string GetOfficeNumber()
{
return this._officeNumber;
}
public void SetOfficeNumber(string input)
{
this._officeNumber = input;
}
public string GetTelePhoneNumber()
{
return $"{this._officeAreaCode}{this._officeNumber}";
}
}
確保都是正確寫個測試。
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var person = new Person();
person.SetOfficeAreaCode("02");
person.SetOfficeNumber("2222-2222");
var telePhoneNumber = person.GetTelePhoneNumber();
telePhoneNumber.Should().Be("022222-2222");
}
}
這邊是在重構前基本的保護措施,為了確保我們的程式碼在更動後仍然會正確的執行。
接著我們可以發現電話相關的部分可以拆分,把跟電話有關的部分搬到一個新建的 TelePhone Class。
這邊 VisualStudio 就沒有甚麼快速的方式可以搬取了,如果是要擷取基底內別可以直接使用 Cirl + . 但這邊不是,而使用 Rider 的朋友就可以快速達成, 可恨R 。
public class TelePhone
{
private string _officeAreaCode;
private string _officeNumber;
public string GetOfficeAreaCode()
{
return this._officeAreaCode;
}
public string GetOfficeNumber()
{
return this._officeNumber;
}
public string GetTelePhoneNumber()
{
return $"{this._officeAreaCode}{this._officeNumber}";
}
public void SetOfficeAreaCode(string input)
{
this._officeAreaCode = input;
}
public void SetOfficeNumber(string input)
{
this._officeNumber = input;
}
}
原先 Person Class 使用到的地方我們改成。
public class Person
{
private string _name;
private TelePhone _telePhone;
public Person()
{
this._telePhone = new TelePhone();
}
public string GetName()
{
return this._name;
}
public void SetName(string input)
{
this._name = input;
}
public string GetOfficeAreaCode()
{
return this._telePhone.GetAreaCode();
}
public string GetOfficeNumber()
{
return this._telePhone.GetAreaCode();
}
public string GetTelePhoneNumber()
{
return this._telePhone.GetTelePhoneNumber();
}
public void SetOfficeAreaCode(string input)
{
this._telePhone.SetAreaCode(input);
}
public void SetOfficeNumber(string input)
{
this._telePhone.SetNumber(input);
}
}
執行一下測試確保這樣搬沒有出錯
接下來我就可以來修改一下命名,首先 TelePhone Class 中 Office 對它本身來說不太有甚麼意義,我們把它拿掉。
這邊可以使用選取後在 VisualStudio 內快捷鍵 Cirl R + R 。
現在 TelePhone Class 變成
public class TelePhone
{
private string _areaCode;
private string _number;
public string GetAreaCode()
{
return this._areaCode;
}
public string GetNumber()
{
return this._number;
}
public string GetTelePhoneNumber()
{
return $"{this._areaCode}{this._number}";
}
public void SetAreaCode(string input)
{
this._areaCode = input;
}
public void SetNumber(string input)
{
this._number = input;
}
}
再執行一下測試確保更名過程沒有任何出錯。
接著回到 Person Class 我們會發現 GetTelePhoneNumber 這個方法有點奇怪。
我們已經知道要拿取的是 TelePhoneNumber 了,在 TelePhone 內的 GetTelePhoneNumber 就顯得有點雞肋。
把它改成
public string GetTelePhoneNumber()
{
return this._telePhone.Get();
}
改完後一樣執行測試確保一切正常。