Skip to content

重构 - 8. 搬移特性

🏷️ 《重构》

8.1 搬移函数(Move Function)

曾用名搬移函数(Move Method)

重构前

csharp
class Account
{
    decimal OverdraftCharge { get; }
}

重构后

csharp
class AccounType
{
    decimal OverdraftCharge { get; }
}

8.2 搬移字段(Move Field)

重构前

csharp
class Customer
{
    public Plan Plan { get; set; }
    public decimal DiscountRate { get; set; }
}

重构后

csharp
class Customer
{
    public Plan Plan { get; set; }
    public decimal DiscountRate
    {
        get
        {
            return Plan.DiscountRate;
        }
    }
}

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>",
    };
}

重构后

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>",
    };
}

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>"));
}

重构后

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>"));
}

8.5 以函数调用取代内联代码(Replace Inline Code with Function Call)

重构前

csharp
var appliesToMass = false;
foreach (var s in states)
{
    if (s == "MA")
    {
        appliesToMass = true;
    }
}

重构后

csharp
var appliesToMass = states.Contains("MA");

8.6 移动语句(Slide Statements)

曾用名合并重复的代码片段(Consolidate Duplicate Conditional Fragments)

重构前

csharp
var pricingPlan = RetrievePricingPlan();
var order = RetreiveOrder();
decimal charge;
var chargePerUnit = pricingPlan.Unit;

重构后

csharp
var pricingPlan = RetrievePricingPlan();
var chargePerUnit = pricingPlan.Unit;
var order = RetreiveOrder();
decimal charge;

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;

重构后

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;

一般在拆分循环后,会考虑对每个循环应用别的重构手法,如提炼函数等

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);
    }
}

重构后

csharp
var names = input.Where(i => i.Job == "programmer").Select(i => i.Name).ToList();

8.9 移除死代码(Remove Dead Code)

重构前

csharp
if (false)
{
    doSomethingThatUsedToMatter();
}

重构后

csharp
// do nothing

附 1. 引用

  1. 《重构:改善既有代码的设计》 -- 马丁·福勒(Martin Fowler