重构代码之取消临时字段

embedded/2024/11/14 11:33:49/

在代码重构中,临时字段是一种常见的反模式。临时字段指的是一个类的字段在部分方法中会被赋值或使用,但在其他很多方法中却未被使用,导致代码的维护性和可读性变差。这种设计往往表明字段的存在是偶然的或局部的,而非类的真正属性。因此,通过消除临时字段,我们可以提升代码的结构性和可读性。

一、为什么临时字段是一个反模式?

临时字段的主要问题在于它增加了类的复杂性,让代码阅读者误以为字段是这个类的核心属性,而实际上它可能只在特定情况下才有用。例如,临时字段通常在只有少数方法中赋值,在其他情况下可能保持 null 或无意义的默认值,这使代码变得难以理解,调试和维护变得复杂。

二、识别临时字段的信号

临时字段的特征通常包括:

  • 字段只在部分方法中被使用,而在其他方法中无意义。
  • 字段在类的大部分时间中为空或无效值。
  • 字段的使用存在多个条件分支,用于检查其是否有效。

三、解决方案

有几种方式可以消除临时字段:

  1. 将字段移入方法
    如果字段只在某个方法或一组方法中使用,那么可以将该字段改为局部变量,限定在方法的作用域内。
  2. 使用辅助类或数据容器
    如果临时字段是多个方法共享的数据,可以将这些字段提取到一个单独的辅助类中,用该类管理它们的状态。这样不仅提升了代码的模块化,还降低了原始类的复杂度。
  3. 引入专用的值对象
    如果临时字段用于特定的计算或数据传输,可以引入一个值对象专门承担这个作用。这样可以确保类的状态更加简洁,且符合单一职责原则。

四、示例

下面是一个 C# 的代码示例,展示了如何识别和重构临时字段。

4.1 重构前的代码
public class OrderProcessor
{private Customer _customer;  // 临时字段private decimal _discount;   // 临时字段,仅在部分方法中使用public void SetCustomer(Customer customer){_customer = customer;}public decimal CalculateDiscount(){if (_customer == null) return 0;_discount = _customer.IsPremium ? 0.1m : 0.05m;return _discount;}public void ProcessOrder(Order order){if (_customer == null) throw new InvalidOperationException("Customer not set");// 处理订单逻辑}
}

在上面的例子中,_customer_discount 字段只是为了完成 CalculateDiscount 方法而存在的,其他方法中则不需要它们。这使得 OrderProcessor 类复杂化,并且 _discount 在其他情况下可能无效。

4.2 重构后的代码
public class OrderProcessor
{public decimal CalculateDiscount(Customer customer){if (customer == null) return 0;return customer.IsPremium ? 0.1m : 0.05m;}public void ProcessOrder(Order order, Customer customer){if (customer == null) throw new InvalidOperationException("Customer not set");// 处理订单逻辑}
}

重构后,我们移除了临时字段 _customer_discount,并将 Customer 参数直接传递给 CalculateDiscountProcessOrder 方法。这样 OrderProcessor 不再依赖于临时状态,类变得更简洁,代码的意图更加明确。

4.3使用 Null Object 模式(进阶用法)

在某些场景中,如果临时字段的空值被频繁检查,Null Object 模式也是一种有效的替代方案。例如,在上述代码中,如果 _customer 的空值情况较多且影响其他代码,可引入 Null Object 替代空值。

五、总结

取消临时字段的重构目的是为了让类的状态更明确,方法的职责更清晰。通过将临时字段转化为局部变量、辅助类或值对象,我们可以增强代码的清晰度,使其更易于维护和扩展。


http://www.ppmy.cn/embedded/137485.html

相关文章

DOM NodeList 探索

DOM NodeList 探索 引言 在Web开发中,文档对象模型(DOM)是核心概念之一。DOM提供了一种以树形结构表示HTML或XML文档的方法,允许开发者通过JavaScript等脚本语言操作文档的结构、样式和内容。在DOM中,NodeList是一个重要的接口,它表示一个节点的集合,通常是由查询DOM树…

JavaScript字符串常用方法

在JavaScript中,字符串是用来表示文本数据的基本数据类型。字符串可以用单引号()、双引号(")、或反引号()包裹。JavaScript中的字符串是不可变的,也就是说,字符串的值一旦创建就无法更改,但可以创建新字符串来替换原有字符串…

[oeasy]python040_缩进几个字符好_输出所有键盘字符_循环遍历_indent

040_缩进几个字符好_输出所有键盘字符_indent 缩进几个字符好? 上次 研究了range函数 根据range函数的结果生成了for循环 可以输出 从start到end - 1所有的数字 想要 循环输出 必须得缩进吗? for num in range(ord(A), ord(Z)1):print(num,chr(num)) 不…

【Webpack配置全解析】打造你的专属构建流程️(4)

webpack 提供的 CLI 支持很多参数,例如 --mode,但更多的时候,我们会使用更加灵活的配置文件来控制 webpack 的行为。默认情况下,webpack 会读取 webpack.config.js 文件作为配置文件,但也可以通过 CLI 参数 --config 来…

POI实现根据PPTX模板渲染PPT

目录 1、前言 2、了解pptx文件结构 3、POI组件 3.1、引入依赖 3.2、常见的类 3.3、实现原理 3.4、关键代码片段 3.4.1、获取ppt实例 3.4.2、获取每页幻灯片 3.4.3、循环遍历幻灯片处理 3.4.3.1、文本 3.4.3.2、饼图 3.4.3.3、柱状图 3.4.3.4、表格 3.4.3.5、本地…

初阶C++之C++入门基础

大家好!欢迎来到C篇学习,这篇文章的内容不会很难,为c的引入,c的重点内容将在第二篇的文章中讲解,届时难度会陡然上升,请做好准备! 我们先看网络上的一个梗:21天内⾃学精通C 好了&am…

私有IP与公网IP

私有IP与公网IP是计算机网络中的两种不同类型的IP地址。它们在网络通信中扮演不同的角色,以下是它们的详细解释和举例: 私有IP(Private IP): 私有IP地址是在本地网络内部使用的IP地址,通常是局域网中的设备…

2024 年将 Swagger 导入 Postman 图文教程

2024 年将 Swagger 导入 Postman 图文教程