重构代码之参数化方法

ops/2024/11/14 2:50:47/

在代码重构中,参数化方法 通过将方法内部的硬编码值替换为参数,使方法的适用性更广。这不仅可以减少重复代码,还能提高代码的灵活性和可维护性。让我们来深入探讨这种技术的应用场景、步骤以及一些例子。

一、适用场景

参数化方法通常适用于以下场景:

  • 硬编码的值需要更改:方法内部使用了固定的值,如果将这些值外部化并传入作为参数,方法可以在不同场景中复用。
  • 逻辑的重复:多个方法中存在相似的代码逻辑,但只有少量变量不同。这时可以通过参数化的方法减少代码重复。
  • 提高扩展性:让方法更加通用,可以在未来的需求变动时灵活适应。

二、重构步骤

  1. 标识硬编码的值
    首先,找出方法中哪些固定值是可变的或可能会在不同情境下变化的。这些值可以是数值、字符串、对象,甚至是方法调用。

  2. 添加参数
    将这些硬编码的值替换为参数,并在方法签名中添加对应的参数。

  3. 更新调用方
    由于方法签名的更改,所有调用该方法的代码都需要传入新的参数。这一步可能需要在多个调用方中更新值,但通常这是值得的,因为这样可以简化代码逻辑和维护成本。

  4. 测试重构后的代码
    重构完成后,确保重构后的代码功能和逻辑仍然与原先一致。单元测试是确保重构成功的一个有效手段。

三、实例演示

示例 1:将硬编码的折扣率替换为参数

假设有一个计算商品折扣的 CalculateDiscount 方法,最初方法中的折扣率是硬编码的。
重构前:

public decimal CalculateDiscount(decimal price)
{decimal discountRate = 0.10m; // 10% discountreturn price * discountRate;
}

重构后:

public decimal CalculateDiscount(decimal price, decimal discountRate)
{return price * discountRate;
}

调用时可以传入不同的折扣率,使该方法更加通用:

var discountA = CalculateDiscount(100m, 0.10m); // 10% discount
var discountB = CalculateDiscount(100m, 0.20m); // 20% discount
示例 2:将硬编码的日志级别参数化

假设一个 LogMessage 方法,最初是写死日志级别为 Info
重构前:

public void LogMessage(string message)
{Console.WriteLine($"[Info] {message}");
}

重构后:

public void LogMessage(string message, string logLevel)
{Console.WriteLine($"[{logLevel}] {message}");
}

调用方可以指定不同的日志级别:

LogMessage("System started", "Info");
LogMessage("Unexpected error occurred", "Error");
LogMessage("User logged out", "Debug");
示例 3:添加额外的运算参数

假设我们有一个求矩形面积的方法 CalculateArea,最初只支持长方形的计算。
重构前:

public double CalculateArea(double length, double width)
{return length * width;
}

重构后:
通过引入一个 shape 参数,我们可以灵活地支持不同的形状:

public double CalculateArea(double length, double width, string shape = "rectangle")
{if (shape == "rectangle"){return length * width;}else if (shape == "triangle"){return (length * width) / 2;}else{throw new ArgumentException("Unsupported shape");}
}

这样方法调用方可以通过传入参数来控制要计算的图形类型:

var rectangleArea = CalculateArea(10, 5);                // 默认长方形
var triangleArea = CalculateArea(10, 5, "triangle");    // 三角形

四、参数化方法的优点

  • 减少重复代码:将类似逻辑抽取为参数化方法,可以避免代码重复,提高代码质量。
  • 增加灵活性:方法的调用方可以根据具体需求传入不同的参数,从而灵活应对各种情况。
  • 提升可维护性:当参数变化时,可以集中在方法内调整,而不是在每个调用处修改硬编码的值。

五、注意事项

  • 参数过多的问题:过多的参数会导致代码难以理解和维护。因此,合理控制参数的数量。如果参数太多,可以考虑使用参数对象或分解方法。
  • 方法的职责单一性:参数化方法可以增强方法的通用性,但仍需确保方法的职责单一,不要将过多的逻辑混合在一个方法中。
  • 保持方法的清晰性:避免让参数变得过于复杂,比如避免传入不同的数据类型让方法执行不同的操作。

参数化方法是一种有效的重构技术,适用于去除硬编码、提升方法通用性的场景。通过这项技术,代码的灵活性、可读性和可维护性都能得到显著提升。然而在使用时,也需保持代码的简洁性,避免过度参数化。


http://www.ppmy.cn/ops/133444.html

相关文章

Spring Security 认证流程,长话简说

一、代码先行 1、设计模式 SpringSecurity 采用的是 责任链 的设计模式,是一堆过滤器链的组合,它有一条很长的过滤器链。 不过我们不需要去仔细了解每一个过滤器的含义和用法,只需要搞定以下几个问题即可:怎么登录、怎么校验账户、认证失败…

泷羽sec学习打卡-Linux基础2

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 关于Linux的那些事儿-Base2 一、Linux-Base2linux有哪些目录呢?不同目录下有哪些具体的文件呢…

C++ 中的异常处理机制是怎样的?

异常处理的基本概念: 异常: 程序在运行时发生的错误或意外情况。 抛出异常: 使用 throw 关键字将异常传递给调用堆栈。 捕获异常: 使用 try-catch 块捕获和处理异常。 异常类型: 表示异常类别的标识符。 异常处理流程: 抛出异常: 当检测到错误或意…

python制作一个简单的端口扫描器,用于检测目标主机上指定端口的开放状态

import argparse # 用于解析命令行参数 from socket import * # 导入 socket 库的所有内容,用于网络通信 from threading import * # 导入 threading 库的所有内容,用于多线程操作 # 创建一个信号量,初始值为 1,用于线程同步&…

NumPy与TensorFlow-tf.tensor异同点

NumPy数组与TenosrFlow中的张量(即tf.tensor)有很多相似地方,而且可以互相转换。下表总结了NumPy与tf.tensor的异同点。 NumPy与tf.tensor的异同点 操作类别NumPyTensorFlow 2数据类型np.ndarraytf.Tensornp.float32tf.float32np.float64tf…

制造企业数字化中台(技术中台、数据中台、业务中台)建设方案

文件是一份关于制造企业数字化中台建设方案的详细报告,由郎丰利1519整理制作。报告内容涵盖了数字化中台的总体解决方案、技术中台(A)、数据中台(B)和业务中台(C)的架构和功能。以下是对PPT内容…

九州未来再度入选2024边缘计算TOP100

随着数智化转型的浪潮不断高涨,边缘计算作为推动各行业智能化升级的重要基石,正在成为支持万物智能化的关键点。近日,德本咨询(DBC)联合《互联网周刊》(CIW)与中国社会科学院信息化研究中心(CIS),共同发布《2024边缘计算TOP100》榜…

算法——移除元素(leetcode27)

对于移除元素这道题来讲,我首先想到的还是双指针,根据题目要求我们需要在给定的一组数组中找出与目标值不同的元素数量并且将与目标值不同的元素全部移至数组左边右边则不需关注数组元素的大小,我们利用两个指针一个指向数组首部位置(左指针&…