重构 - 8. 搬移特性

8.1 搬移函数(Move Function)

曾用名搬移函数(Move Method)

重构前

class Account
{
    decimal OverdraftCharge { get; }
}
  

重构后

class AccounType
{
    decimal OverdraftCharge { get; }
}
  

8.2 搬移字段(Move Field)

重构前

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

重构后

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

8.3 搬移语句到函数(Move Statement into Function)

反向重构搬移语句到调用者(Move Statements to Caller)

重构前

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

重构后

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)

重构前

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

重构后

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)

重构前

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

重构后

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

8.6 移动语句(Slide Statements)

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

重构前

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

重构后

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

8.7 拆分循环(Split Loop)

重构前

var averageAge = 0;
var totalSalary = 0;
foreach (var p in people)
{
    averageAge += p.Age;
    totalSalary += p.Salary;
}
averageAge = averageAge / people.Length;
  

重构后

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)

重构前

var names = new List<string>();
foreach (var i in input)
{
    if (i.Job == "programmer")
    {
        names.Add(i.Name);
    }
}
  

重构后

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

8.9 移除死代码(Remove Dead Code)

重构前

if (false)
{
    doSomethingThatUsedToMatter();
}
  

重构后

// do nothing
  

附 1. 引用

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