C#遗留代码重构:逐步指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为何重构遗留C#代码势在必行



每位.NET开发者迟早都会遇到遗留代码。这不一定是20年前基于.NET Framework 1.1的项目——往往一年前匆忙编写、没有测试且违反SOLID原则的代码就会变成"遗留代码"。处理这样的代码无异于噩梦:任何修改都可能在意外的地方破坏功能,理解逻辑只能依靠调试。



重构并非从头重写。它是在不改变外部行为的前提下改善代码的内部结构。本文将分析一些可立即应用的实际重构技术,帮助您以最小风险重构遗留C#代码。



1. 准备工作:重构的黄金法则



在修改代码之前,请确保您拥有"安全网"——一套自动化测试。没有测试的重构无异于盲人摸象。



创建特征测试

如果没有测试,请编写特征测试(也称为golden master测试或快照测试)。思路很简单:用不同的输入数据运行方法,记录结果,然后验证重构后结果是否保持不变。



// 遗留方法的特征测试示例[Test]public void CalculateTotal_ShouldReturnSameResult_AfterRefactoring(){    // 准备    var order = new Order { Items = new List<Item> { new Item { Price = 100, Quantity = 2 } } };    var expected = 200; // 已知结果

// 执行 var result = LegacyOrderCalculator.CalculateTotal(order);

// 断言 Assert.AreEqual(expected, result);}


提示:使用 Verify 或 ApprovalTests 等库进行自动快照测试。



2. 技术#1:提取方法



最简单且最有效的技术。当您看到一段200行的方法,里面充斥着"// 此处计算折扣"之类的注释时——它便是理想的候选对象。



示例:大型方法



public decimal ProcessOrder(Order order){    decimal total = 0;    foreach (var item in order.Items)    {        total += item.Price * item.Quantity;    }

// 折扣计算 if (order.Customer.IsPremium) { total *= 0.9m; // 10%折扣 } else if (order.TotalAmount > 1000) { total *= 0.95m; // 5%折扣 }

// 应用税收 total *= 1.2m; // 20%税额

return total;}


重构之后



public decimal ProcessOrder(Order order){    decimal subtotal = CalculateSubtotal(order.Items);    decimal afterDiscount = ApplyDiscount(subtotal, order.Customer);    return ApplyTax(afterDiscount);}

private decimal CalculateSubtotal(IEnumerable<Item> items){ return items.Sum(item => item.Price * item.Quantity);}

private decimal ApplyDiscount(decimal total, Customer customer){ if (customer.IsPremium) return total * 0.9m; if (total > 1000) return total * 0.95m; return total;}

private decimal ApplyTax(decimal amount){ return amount * 1.2m;}


优点:

  • 每个方法职责单一
  • 代码变得可读且可测试
  • 折扣逻辑可在其他位置复用


3. 技术#2:用多态取代条件逻辑



遗留代码中经常存在漫长的 if-else 或 switch 语句链。这违反了开闭原则(OCP)。



示例:按文档类型进行Switch判断



public decimal CalculateShippingCost(Order order){    switch (order.ShippingType)    {        case "Standard":            return 5;        case "Express":            return 15;        case "Overnight                

博客

书籍推荐