简介
"将函数合并到类中"(Combine Functions into Class)是一种重构手法,它的目的是将一组功能相关的函数组织到一个类中,以提高代码的内聚性和可维护性。这种重构手法有助于将分散的功能进行集中管理,使代码结构更加清晰,避免功能的碎片化,便于理解和维护。
针对的症状(代码坏味道)
- 分散的函数(Scattered Functions):多个函数在不同的类或模块中执行相似或相关的操作,但没有被合理地组织在一起,导致代码逻辑分散。
- 低内聚性(Low Cohesion):代码的功能被分散在多个类或模块中,使得代码的内聚性降低,难以理解其整体功能。
- 功能关联不明确:一些函数虽然功能相关,但它们的关联关系不明显,因为它们分散在不同的位置,导致代码的可读性和可维护性变差。
将函数合并到类中(Combine Functions into Class)的详细步骤
- 识别相关函数
- 寻找功能相关的函数:分析代码库,找出那些执行相似或相关操作的函数,例如处理同一业务领域的函数,或者对同一组数据进行操作的函数。
- 确定共同的职责:确定这些函数的共同职责或功能范围,以便将它们放入一个统一的类中。
- 创建新类
- 选择合适的类名:为新类选择一个能够准确描述这些函数共同功能的名称,以反映它们的职责。
- 定义类的属性:根据这些函数所操作的数据或依赖的资源,确定类需要的属性。
- 确保类的单一职责原则:新类应该遵循单一职责原则,只负责一个主要的功能领域。
- 迁移函数
- 将识别出的函数迁移到新类中:将这些函数从原来的类或模块中移到新创建的类中。
- 调整函数的参数和返回值:根据新类的属性和结构,调整函数的参数和返回值,使其能够在新类中正确工作。
- 处理依赖关系:将函数中涉及的外部依赖转换为新类的属性或通过构造函数注入,避免直接依赖外部类或模块。
- 替换原始调用
- 在原始调用处使用新类的实例:在原来调用这些函数的地方,使用新类的实例来调用迁移后的函数。
- 确保调用正确:验证新类的实例调用函数的方式正确,不会影响原有的功能。
- 测试
- 编译代码:确保代码编译通过,没有任何语法错误。
- 运行测试:运行所有相关的单元测试,确保重构操作没有引入新的错误。
- 手动测试:如果有必要,进行手动测试以验证功能的正确性。
- 代码审查
- 同行评审:让同事或其他团队成员审查你的更改,确保代码质量和可维护性得到提升。
- 文档更新:如果项目有维护文档的习惯,记得更新相关文档,说明重构的影响。
示例
假设有以下 Java 代码,其中有一些分散的函数处理用户相关的操作:
java
class UserUtils {
public static String formatUserFullName(String firstName, String lastName) {
return firstName + " " + lastName;
}
}
class UserAuthentication {
public static boolean authenticate(String username, String password) {
// 假设这里有一些认证逻辑
return username.equals("admin") && password.equals("admin");
}
}
步骤如下:
-
识别相关函数:
UserUtils.formatUserFullName
和UserAuthentication.authenticate
都与用户操作相关。
-
创建新类:
-
创建一个名为
UserService
的新类,将这些函数整合进去。javaclass UserService { public String formatUserFullName(String firstName, String lastName) { return firstName + " " + lastName; } public boolean authenticate(String username, String password) { // 假设这里有一些认证逻辑 return username.equals("admin") && password.equals("admin"); } }
-
-
迁移函数:
- 将
UserUtils.formatUserFullName
和UserAuthentication.authenticate
函数移到UserService
类中。
- 将
-
替换原始调用:
-
原来调用这些函数的地方,使用
UserService
类的实例进行调用。javapublic class Main { public static void main(String[] args) { UserService userService = new UserService(); String fullName = userService.formatUserFullName("John", "Doe"); boolean isAuthenticated = userService.authenticate("admin", "admin"); } }
-
-
测试:
- 编译代码,确保代码编译通过。
- 运行测试:运行所有相关的单元测试,确保重构操作没有引入新的错误。
- 手动测试:手动调用
UserService
类的方法,验证功能的正确性。
-
代码审查:
- 让同事审查代码,确保代码的内聚性得到提升,且没有引入新的问题。
练习
基础练习题
-
合并订单处理函数
-
给定以下 Java 代码,
OrderUtils
类和OrderManager
类中都有一些与订单处理相关的函数,但它们分散在不同的类中。请将它们合并到一个新类中。javaclass OrderUtils { public static double calculateOrderTotal(double price, int quantity) { return price * quantity; } } class OrderManager { public static void processOrder(double total) { System.out.println("Processing order with total: " + total); } }
-
-
整合支付处理函数
-
以下是
PaymentGateway
类和PaymentProcessor
类中的函数,它们都与支付处理相关。请将它们合并到一个新类中。javaclass PaymentGateway { public static boolean validatePayment(String cardNumber) { // 假设这里有一些验证逻辑 return cardNumber.startsWith("1234"); } } class PaymentProcessor { public static void processPayment(String cardNumber) { if (PaymentGateway.validatePayment(cardNumber)) { System.out.println("Payment processed successfully."); } else { System.out.println("Payment validation failed."); } } }
-
进阶练习题
-
合并复杂业务逻辑函数
-
在以下 Java 代码中,
InventoryManager
类和StockUpdater
类有与库存管理相关的函数。将它们合并到一个新类中,并处理好依赖关系和参数调整。javaclass InventoryManager { public static int checkStockLevel(String productId) { // 假设这里有一些库存检查逻辑 return 10; } } class StockUpdater { public static void updateStock(String productId, int quantity) { System.out.println("Updating stock for product " + productId + " by " + quantity); } }
-
-
整合数据处理函数
-
考虑
DataParser
类和DataValidator
类中的函数,它们都与数据处理和验证相关。将它们合并到一个新类中,并确保新类遵循单一职责原则。javaclass DataParser { public static String parseData(String rawData) { // 假设这里有一些解析逻辑 return "Parsed data"; } } class DataValidator { public static boolean validateData(String data) { // 假设这里有一些验证逻辑 return data.contains("valid"); } }
-
综合拓展练习题
- 多模块函数合并与优化
-
假设有一个简单的电子商务系统,其中有
ProductService
类、ProductCatalog
类和ProductReview
类,它们包含了与产品相关的函数,如产品信息的获取、产品目录的管理和产品评论的处理。 -
请将这些类中的相关函数合并到一个新类中,命名为
ProductManagementService
。 -
模拟一份代码审查报告,指出重构后的优点和可能存在的潜在问题。
javaclass ProductService { public static Product getProductById(int id) { // 假设这里有一些获取产品的逻辑 return new Product(); } } class ProductCatalog { public static void addProduct(Product product) { // 假设这里有一些添加产品到目录的逻辑 } } class ProductReview { public static void addReview(Product product, String review) { // 假设这里有一些添加评论的逻辑 } }
-
在这个重构过程中,我们将这些分散的函数合并到一个类中,以提高代码的内聚性和可维护性,同时需要注意保持代码的清晰性和遵循单一职责原则。