重构 - 8. 搬移特性
🏷️ 《重构》
8.1 搬移函数(Move Function)
曾用名:搬移函数(Move Method)
重构前:
csharp
class Account
{
decimal OverdraftCharge { get; }
}
1
2
3
4
2
3
4
重构后:
csharp
class AccounType
{
decimal OverdraftCharge { get; }
}
1
2
3
4
2
3
4
8.2 搬移字段(Move Field)
重构前:
csharp
class Customer
{
public Plan Plan { get; set; }
public decimal DiscountRate { get; set; }
}
1
2
3
4
5
2
3
4
5
重构后:
csharp
class Customer
{
public Plan Plan { get; set; }
public decimal DiscountRate
{
get
{
return Plan.DiscountRate;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
8.3 搬移语句到函数(Move Statement into Function)
反向重构:搬移语句到调用者(Move Statements to Caller)
重构前:
csharp
result.Add($"<p>title: {aPerson.Photo.Title}</p>");
result.AddRange(PhotoData(aPerson.Photo));
static string[] PhotoData(Photo aPhoto)
{
return new string[] {
$"<p>location: {aPhoto.Location}</p>",
$"<p>date: {aPhoto.Date:yyyy-MM-dd}</p>",
};
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
重构后:
csharp
result.AddRange(PhotoData(aPerson.Photo));
static string[] PhotoData(Photo aPhoto)
{
return new string[] {
$"<p>title: {aPhoto.Title}</p>",
$"<p>location: {aPhoto.Location}</p>",
$"<p>date: {aPhoto.Date:yyyy-MM-dd}</p>",
};
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
8.4 搬移语句到调用者(Move Statements to Callers)
反向重构:搬移语句到函数(Move Statement into Function)
重构前:
csharp
EmitPhotoData(outStram, aPerson.Photo);
void EmitPhotoData(Stream outStram, Photo aPhoto)
{
outStram.Write(Encoding.UTF8.GetBytes($"<p>title: {aPhoto.Title}</p>"));
outStram.Write(Encoding.UTF8.GetBytes($"<p>location: {aPhoto.Location}</p>"));
}
1
2
3
4
5
6
7
2
3
4
5
6
7
重构后:
csharp
EmitPhotoData(outStram, aPerson.Photo);
outStram.Write(Encoding.UTF8.GetBytes($"<p>location: {aPerson.Photo.Location}</p>"));
void EmitPhotoData(Stream outStram, Photo aPhoto)
{
outStram.Write(Encoding.UTF8.GetBytes($"<p>title: {aPhoto.Title}</p>"));
}
1
2
3
4
5
6
7
2
3
4
5
6
7
8.5 以函数调用取代内联代码(Replace Inline Code with Function Call)
重构前:
csharp
var appliesToMass = false;
foreach (var s in states)
{
if (s == "MA")
{
appliesToMass = true;
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
重构后:
csharp
var appliesToMass = states.Contains("MA");
1
8.6 移动语句(Slide Statements)
曾用名:合并重复的代码片段(Consolidate Duplicate Conditional Fragments)
重构前:
csharp
var pricingPlan = RetrievePricingPlan();
var order = RetreiveOrder();
decimal charge;
var chargePerUnit = pricingPlan.Unit;
1
2
3
4
2
3
4
重构后:
csharp
var pricingPlan = RetrievePricingPlan();
var chargePerUnit = pricingPlan.Unit;
var order = RetreiveOrder();
decimal charge;
1
2
3
4
2
3
4
8.7 拆分循环(Split Loop)
重构前:
csharp
var averageAge = 0;
var totalSalary = 0;
foreach (var p in people)
{
averageAge += p.Age;
totalSalary += p.Salary;
}
averageAge = averageAge / people.Length;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
重构后:
csharp
var totalSalary = 0;
foreach (var p in people)
{
totalSalary += p.Salary;
}
var averageAge = 0;
foreach (var p in people)
{
totalSalary += p.Salary;
}
averageAge = averageAge / people.Length;
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
一般在拆分循环后,会考虑对每个循环应用别的重构手法,如提炼函数等
8.8 以管道取代循环(Replace Loop with Pipeline)
重构前:
csharp
var names = new List<string>();
foreach (var i in input)
{
if (i.Job == "programmer")
{
names.Add(i.Name);
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
重构后:
csharp
var names = input.Where(i => i.Job == "programmer").Select(i => i.Name).ToList();
1
8.9 移除死代码(Remove Dead Code)
重构前:
csharp
if (false)
{
doSomethingThatUsedToMatter();
}
1
2
3
4
2
3
4
重构后:
csharp
// do nothing
1
附 1. 引用
- 《重构:改善既有代码的设计》 -- 马丁·福勒(Martin Fowler)