重构长方法之以方法对象取代方法

ops/2024/10/18 5:21:58/

以方法对象取代方法重构长方法的一种技术,适用于那些过长、逻辑复杂且难以拆解的单一方法。此方法通过引入一个新的类,将原本庞杂的方法转化为一个对象方法,这样可以更容易将方法中的不同步骤拆解为多个私有方法,使代码结构清晰,易于维护。

一、问题背景

长方法常常包含多步逻辑或复杂的计算,导致代码难以理解和修改。如果只是简单地将方法分割成多个小方法,可能还不够,因为这些小方法通常需要共享一些局部变量。直接将方法拆解为多个小方法,可能会导致参数传递繁琐,难以维持一致性。

二、重构思路

通过引入一个新的类(方法对象),你可以将长方法内的逻辑逐步拆解到该类中。这样一来,局部变量可以成为方法对象的字段,从而避免在多个方法间传递大量参数,同时方法中的各个步骤也能被分离成单独的小方法,进一步提高代码的可读性。

三、重构过程

假设我们有一个非常复杂的计算方法:

public double CalculateTotalPrice(double price, double taxRate, double discount)
{double tax = price * taxRate;double discountedPrice = price - discount;double totalPrice = discountedPrice + tax;if (discountedPrice < 0){throw new ArgumentException("Discount cannot be greater than price");}//-------------------------//Long Code//-------------------------return totalPrice;
}

这是一个典型的长方法,包含了计算税费、折扣以及一些错误检查逻辑等。虽然在现在它还不算太复杂,但随着需求增加这个方法很容易变得臃肿和难以维护。

四、重构:引入方法对象

  1. 创建新类:将这个计算逻辑提取到一个新的类中,称为 PriceCalculator
  2. 将局部变量转化为字段:在新的类中,所有的局部变量和传入参数变成类的字段。
  3. 将不同的逻辑拆分为独立方法:将各个步骤逻辑分离为私有方法,从而保持代码清晰。

重构后的代码:

public class PriceCalculator
{private double price;private double taxRate;private double discount;public PriceCalculator(double price, double taxRate, double discount){this.price = price;this.taxRate = taxRate;this.discount = discount;}public double CalculateTotalPrice(){double discountedPrice = ApplyDiscount();ValidatePrice(discountedPrice);double tax = CalculateTax();return discountedPrice + tax;}private double ApplyDiscount(){return price - discount;}private double CalculateTax(){return price * taxRate;}private void ValidatePrice(double discountedPrice){if (discountedPrice < 0){throw new ArgumentException("Discount cannot be greater than price");}}
}

调用方式:

var calculator = new PriceCalculator(price, taxRate, discount);
double totalPrice = calculator.CalculateTotalPrice();

五、优点和缺点

5.1 优点
  1. 更好地组织代码:通过方法对象将复杂的计算逻辑拆解为多个方法,代码结构变得更清晰。
  2. 减少参数传递:局部变量变成了对象的字段,不需要频繁地在方法之间传递参数。
  3. 便于后续扩展:如果未来需要对某些步骤进行修改或增加新步骤,直接在这个类中修改或添加即可,符合单一职责原则。
  4. 提高可测试性:每个方法都可以单独进行测试,方法的分离使得代码更容易被单元测试覆盖。
5.2 缺点
  1. 增加类的数量:引入新的类虽然可以组织代码,但也会增加项目中的类数量。如果每次遇到长方法都使用方法对象进行重构,可能会导致项目中有过多的小类,增加代码库的复杂性,影响类的管理和维护。
  2. 增加理解成本:对于开发人员来说,引入新类可能会使代码结构变得更加分散。尤其是在代码库中类数量较多时,理解这些类之间的关系可能需要额外的认知负担。特别是对于新成员,可能需要更多时间去理清哪些类是核心业务逻辑,哪些类是为了拆解方法而创建的。
  3. 可能带来过度设计:有时长方法中的逻辑并不复杂,直接拆分为几个私有方法即可。如果引入方法对象,可能会显得过于复杂化,属于“过度设计”。如果一个方法并不复杂,引入额外的类反而增加了不必要的复杂度。
  4. 方法对象可能缺乏复用性:方法对象通常是为了某个具体方法服务的,因此这些类通常只在一个地方使用,导致它们缺乏复用价值。除非有多个类似的长方法使用相同的逻辑,否则引入的类很可能只能局限于某一场景,增加了代码的碎片化。
  5. 调试复杂性:将一个长方法拆解成多个方法后,调试过程中可能需要频繁地跳转到不同的类和方法进行检查。如果方法的逻辑全部集中在一个地方,调试时可以一目了然;但拆解到多个方法或类后,跟踪代码执行路径可能变得更加复杂。
  6. 性能影响(极少见):在极少数情况下,如果每次重构都会创建新的对象,并且这些对象的创建和销毁发生得非常频繁(比如在高性能的实时系统中),可能会引入额外的性能开销。不过在大多数业务系统中,这种开销微不足道。
  7. 类的职责边界模糊:方法对象是一个临时的类,专门为了处理一个方法的复杂逻辑。这些类的职责与实际业务无关,因此在架构上,这些类的职责边界可能不如业务类那么清晰。这可能会给架构的整体设计带来一些混乱。

六、适用场景

  • 当一个方法逻辑复杂且包含多个步骤时,使用“方法对象”能将其分解为多个逻辑上独立的部分。
  • 如果重构需要频繁共享局部变量,直接拆分成子方法会使参数传递复杂化,这时引入一个方法对象可以简化参数处理。

七、总结

“以方法对象取代方法”是一种有效的重构技巧,适合用于处理复杂、臃肿的长方法。通过将方法拆解到一个新的类中,并以类的字段形式处理局部变量,既可以保持代码的简洁,又可以避免参数传递过多的问题,同时也为后续的扩展和维护提供了方便。


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

相关文章

python实现屏幕录制,录音录制工具

python实现屏幕录制&#xff0c;录音录制工具 一&#xff0c;介绍 Python 实现的屏幕录制和录音录制工具是一个便捷的应用程序&#xff0c;旨在帮助用户同时捕捉计算机屏幕上的活动以及与之相关的音频输出。这个工具尤其针对教育工作者、内容创作者、技术支持人员以及任何需要…

数据库的相关概念

先看与数据库有关的几个名词&#xff1a; DB&#xff1a;database&#xff0c;数据库&#xff0c;里边保存了有组织的规范的数据。 DBMS&#xff1a;database management system &#xff0c; 数据库管理系统&#xff0c;简称数据库软件&#xff0c;数据库产品&#xff0c;数…

Python操作MySQL数据库:基础教程与示例代码

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

【数据分享】全国资源和环境-环境污染治理投资(1998-2021年)

数据介绍 一级标题指标名称单位指标解释资源和环境环境污染治理投资总额亿元环境污染治理投资指在污染源治理和城市环境基础设施建设的资金投入中&#xff0c;用于形成固定资产的资金&#xff0c;其中污染源治理投资包括工业污染源治理投资和“三同时”项目环保投资两部分。环…

解决高版本使用Gson报错Caused by: java.lang.NoClassDefFoundError: java/sql/Time

开发项目使用jdk21&#xff0c;版本较高&#xff0c;需要用模块化引入。在使用gson转换json数据时&#xff0c;报错 Caused by: java.lang.NoClassDefFoundError: java/sql/Time at gson2.8.5/com.google.gson.Gson.<init>(Gson.java:265) at gson2.8.5/com.google.gson…

ChatGPT写出优质论文的关键第一步:角色预设提示词指令

在使用ChatGPT做学术研究和论文写作中,有效的提示词指令可以帮助我们更好地利用智能AI工具来提升工作效率和质量。在整个操作过程中,首要第一步就是角色预设的指令,这是能否使用ChatGPT高效写出优质论文的关键步骤。以下是五个重要且常用到的学术角色的预设提示词指令 一、…

YZ系列工具之YZ09:VBA_Excel之读心术

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套一部VBA手册&#xff0c;教程分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的…

Spring Boot知识管理系统:敏捷开发实践

3系统分析 3.1可行性分析 通过对本知识管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本知识管理系统采用JAVA作为开发语言&#xff0c;Spring Boot框…