简介
"拆分循环"是优化代码结构的重要重构手法。通过将承担多重职责的循环分解为多个单一职责的循环,可以提高代码可读性、便于性能优化并增强可维护性。
针对的症状(代码坏味道)
- 循环内处理多个不相关任务
- 存在需要重复遍历的集合
- 循环变量承担过多职责
- 难以单独测试循环中的某个逻辑
拆分循环的详细步骤
- 识别多重职责
- 查找循环中的独立任务块
- 标记不同业务逻辑边界
- 准备中间数据结构
- 创建临时集合存储中间结果
- 提取共享变量到独立结构
- 拆分循环结构
- 为每个职责创建独立循环
- 保持业务逻辑不变
- 优化性能
- 评估时间复杂度
- 必要时合并同类操作
示例
重构前代码:
void processEmployees(List<Employee> employees) {
double totalSalary = 0;
List<Employee> managers = new ArrayList<>();
for (Employee emp : employees) {
// 计算总薪资
totalSalary += emp.getSalary();
// 收集经理
if (emp.isManager()) {
managers.add(emp);
}
}
}
重构后代码:
void processEmployees(List<Employee> employees) {
// 第一个循环计算总薪资
double totalSalary = employees.stream()
.mapToDouble(Employee::getSalary)
.sum();
// 第二个循环收集经理
List<Employee> managers = employees.stream()
.filter(Employee::isManager)
.collect(Collectors.toList());
}
练习
基础练习题
-
简单循环拆分
// 重构前 void analyzeOrders(List<Order> orders) { int count = 0; double total = 0; for (Order o : orders) { count++; total += o.getAmount(); } }
进阶练习题
-
复合逻辑分离
// 重构前 void processData(List<Data> dataset) { Map<String, Integer> counters = new HashMap<>(); List<Data> validData = new ArrayList<>(); for (Data d : dataset) { if (d.isValid()) { validData.add(d); counters.merge(d.getType(), 1, Integer::sum); } } }
综合拓展练习题
-
性能敏感场景
// 重构前 void handleTransactions(List<Transaction> txns) { List<Transaction> frauds = new ArrayList<>(); BigDecimal balance = BigDecimal.ZERO; for (Transaction t : txns) { balance = balance.add(t.getAmount()); if (t.isSuspicious()) { frauds.add(t); } } }
代码审查要点
-
优点:
- 提高代码可读性
- 方便逻辑复用
- 支持并行处理
-
潜在问题:
- 注意时间复杂度变化
- 控制中间数据结构大小
- 保持原子操作完整性