当前位置: 首页 > article >正文

重构之提取类

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

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


http://www.kler.cn/a/376095.html

相关文章:

  • js、vue、angular中的函数声明方式及特点
  • 系统安全架构的深度解析与实践:Java代码实现
  • SPA和SSR
  • Android里的协程( Coroutine)理解
  • WPF+MVVM案例实战(十)- 水波纹按钮实现与控件封装
  • linux 安装php扩展:xlswriter
  • java项目中如何有效提高List集合的读写速度?
  • Angular实现gridview效果
  • 推荐一款老牌音乐制作宿主软件:MOTU Digital Performer
  • 可编辑97页PPT | 制造企业数字化转型战略咨询及IT总体规划方案
  • 浅谈人工智能之DB-GPT(番外篇)Chat Excel功能示例
  • 李宏毅生成对抗网络课程学习笔记(1)
  • mysql上课总结(5)(MySQL的完整性约束(详细介绍))
  • torch.gather和torch.take和torch.stack的等效替换
  • AI-基本概念-多层感知器模型/CNN/RNN/自注意力模型
  • 操作符习题练习
  • C语言 | Leetcode C语言题解之第519题随机翻转矩阵
  • 金华迪加 现场大屏互动系统 mobile.do.php 任意文件上传漏洞复现
  • R 数据框
  • RabbitMQ 存储机制
  • 像`npm i`作为`npm install`的简写一样,使用`pdm i`作为`pdm install`的简写
  • ARM base instruction -- madd
  • 函数的多返回值及多种传参方式
  • Python 的基本语法
  • 【C#】异步和多线程
  • 速度!双击文件就可以运行本地大模型!神奇的AI大模型开源项目——llamafile