重构之提取类

发布于:2024-11-02 ⋅ 阅读:(59) ⋅ 点赞:(0)

重构中的提取类是一种将单个类的职责分离到多个类中的技术。当类变得过于复杂、承担的职责过多时,可以通过提取类来将一些职责单独放到新的类中,从而提高代码的可读性、可维护性,并且使代码更加符合单一职责原则。
下面我们来具体看一下如何进行Extract Class的重构。

一、重构前的代码

假设我们有一个Customer类,该类承担了客户信息和账单处理的职责,这就违反了单一职责原则。代码如下:

public class Customer
{
    public string Name { get; set; }
    public string Email { get; set; }
    public List<Order> Orders { get; set; }

    public Customer(string name, string email)
    {
        Name = name;
        Email = email;
        Orders = new List<Order>();
    }

    // 客户相关方法
    public void AddOrder(Order order)
    {
        Orders.Add(order);
    }

    // 账单相关方法
    public decimal GetTotalBillingAmount()
    {
        return Orders.Sum(order => order.Amount);
    }

    public void PrintBillingStatement()
    {
        Console.WriteLine($"Billing Statement for {Name}");
        foreach (var order in Orders)
        {
            Console.WriteLine($"Order {order.Id}: {order.Amount:C}");
        }
        Console.WriteLine($"Total: {GetTotalBillingAmount():C}");
    }
}

public class Order
{
    public int Id { get; set; }
    public decimal Amount { get; set; }

    public Order(int id, decimal amount)
    {
        Id = id;
        Amount = amount;
    }
}

在这个例子中,Customer类包含了客户信息、订单管理和账单打印等功能。账单管理的代码可以提取出来,形成一个单独的Billing类。

二、重构后的代码

我们可以将账单相关的代码提取到一个Billing类中。重构后的代码如下:

public class Customer
{
    public string Name { get; set; }
    public string Email { get; set; }
    public List<Order> Orders { get; set; }
    public Billing Billing { get; }

    public Customer(string name, string email)
    {
        Name = name;
        Email = email;
        Orders = new List<Order>();
        Billing = new Billing(this); // 将当前客户传递给Billing类
    }

    // 客户相关方法
    public void AddOrder(Order order)
    {
        Orders.Add(order);
    }
}

public class Billing
{
    private readonly Customer _customer;

    public Billing(Customer customer)
    {
        _customer = customer;
    }

    public decimal GetTotalBillingAmount()
    {
        return _customer.Orders.Sum(order => order.Amount);
    }

    public void PrintBillingStatement()
    {
        Console.WriteLine($"Billing Statement for {_customer.Name}");
        foreach (var order in _customer.Orders)
        {
            Console.WriteLine($"Order {order.Id}: {order.Amount:C}");
        }
        Console.WriteLine($"Total: {GetTotalBillingAmount():C}");
    }
}

public class Order
{
    public int Id { get; set; }
    public decimal Amount { get; set; }

    public Order(int id, decimal amount)
    {
        Id = id;
        Amount = amount;
    }
}

三、分析重构后的代码

  1. 将账单逻辑提取到Billing类:现在账单计算和打印的逻辑位于Billing类中,而不再属于Customer类。Billing类专注于与账单相关的操作,符合单一职责原则。
  2. 简化Customer类:现在Customer类的职责仅限于客户信息和订单的管理,不再负责账单处理的逻辑。
  3. 提高可维护性:随着应用的扩展,Billing类可以独立修改和扩展,而不会影响Customer类。

通过这种重构方式,我们将复杂的职责分离,使代码更具可读性和扩展性。