news 2026/2/13 12:45:32

代码重构艺术:烂代码改造与设计模式实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
代码重构艺术:烂代码改造与设计模式实战

引言:何为好代码?

在软件工程领域,重构被比作"整理代码的房间"。好的代码不仅要能工作,还应具备可读性、可维护性和可扩展性。让我们从一个真实案例开始,探索重构的艺术。

第一部分:重构前的"烂代码"分析

1.1 典型烂代码特征

让我们先看一个电商系统中订单处理的典型烂代码:

java

// 重构前:违反几乎所有设计原则的代码 public class OrderProcessor { public void processOrder(String orderId, String customerType, boolean isDiscount, double discountRate, boolean isGiftWrap, boolean isExpressShipping) { // 1. 验证订单 if (orderId == null || orderId.isEmpty()) { System.out.println("订单ID无效"); return; } // 2. 计算价格 double basePrice = getBasePrice(orderId); double finalPrice = basePrice; if (isDiscount) { finalPrice = basePrice * (1 - discountRate); } // 3. 处理礼品包装 if (isGiftWrap) { finalPrice += 10.0; System.out.println("添加礼品包装"); // 发送包装通知 sendGiftWrapNotification(orderId); } // 4. 处理快递运输 if (isExpressShipping) { finalPrice += 25.0; System.out.println("添加快递运输"); // 更新库存 updateInventoryForExpress(orderId); } // 5. 保存订单 saveOrderToDatabase(orderId, finalPrice); // 6. 发送通知 if (customerType.equals("VIP")) { sendVIPNotification(orderId); } else if (customerType.equals("Regular")) { sendRegularNotification(orderId); } else if (customerType.equals("New")) { sendNewCustomerNotification(orderId); } // 7. 生成报告 generateReport(orderId, "daily"); // 8. 更新用户积分 updateCustomerPoints(orderId, customerType); System.out.println("订单处理完成"); } // 数十个辅助方法混杂在一起... private double getBasePrice(String orderId) { /* 实现 */ } private void saveOrderToDatabase(String orderId, double price) { /* 实现 */ } private void sendGiftWrapNotification(String orderId) { /* 实现 */ } private void updateInventoryForExpress(String orderId) { /* 实现 */ } // ... 更多方法 }

1.2 代码问题诊断

  1. 违反单一职责原则:一个方法做太多事情

  2. 违反开闭原则:添加新功能需要修改现有代码

  3. 长方法反模式:方法过长,难以理解和维护

  4. 条件语句滥用:if-else链难以扩展

  5. 紧耦合:业务逻辑与通知、数据库操作紧密耦合

第二部分:重构策略与设计模式应用

2.1 第一步:应用单一职责原则

java

// 重构第一步:职责分离 public class OrderValidator { public boolean validateOrder(String orderId) { return orderId != null && !orderId.isEmpty(); } } public class PriceCalculator { public double calculatePrice(String orderId, DiscountStrategy discountStrategy, List<OrderDecorator> decorators) { double basePrice = getBasePrice(orderId); double price = discountStrategy.applyDiscount(basePrice); for (OrderDecorator decorator : decorators) { price = decorator.decorate(price); } return price; } } public class NotificationService { public void sendNotification(String orderId, CustomerType customerType) { NotificationStrategy strategy = NotificationFactory.createStrategy(customerType); strategy.send(orderId); } }

2.2 第二步:应用策略模式处理折扣

java

// 策略模式:封装变化的折扣算法 public interface DiscountStrategy { double applyDiscount(double price); } public class NoDiscountStrategy implements DiscountStrategy { @Override public double applyDiscount(double price) { return price; } } public class PercentageDiscountStrategy implements DiscountStrategy { private double percentage; public PercentageDiscountStrategy(double percentage) { this.percentage = percentage; } @Override public double applyDiscount(double price) { return price * (1 - percentage); } } public class FixedAmountDiscountStrategy implements DiscountStrategy { private double amount; public FixedAmountDiscountStrategy(double amount) { this.amount = amount; } @Override public double applyDiscount(double price) { return Math.max(0, price - amount); } } // 使用策略模式的折扣计算器 public class DiscountCalculator { private DiscountStrategy strategy; public void setStrategy(DiscountStrategy strategy) { this.strategy = strategy; } public double calculateDiscountedPrice(double originalPrice) { return strategy.applyDiscount(originalPrice); } }

2.3 第三步:应用装饰者模式处理订单附加服务

java

// 装饰者模式:动态添加订单功能 public interface OrderComponent { double getCost(); String getDescription(); } public class BasicOrder implements OrderComponent { private double basePrice; public BasicOrder(double basePrice) { this.basePrice = basePrice; } @Override public double getCost() { return basePrice; } @Override public String getDescription() { return "基础订单"; } } public abstract class OrderDecorator implements OrderComponent { protected OrderComponent decoratedOrder; public OrderDecorator(OrderComponent decoratedOrder) { this.decoratedOrder = decoratedOrder; } @Override public double getCost() { return decoratedOrder.getCost(); } @Override public String getDescription() { return decoratedOrder.getDescription(); } } public class GiftWrapDecorator extends OrderDecorator { public GiftWrapDecorator(OrderComponent decoratedOrder) { super(decoratedOrder); } @Override public double getCost() { return super.getCost() + 10.0; } @Override public String getDescription() { return super.getDescription() + ", 礼品包装"; } } public class ExpressShippingDecorator extends OrderDecorator { public ExpressShippingDecorator(OrderComponent decoratedOrder) { super(decoratedOrder); } @Override public double getCost() { return super.getCost() + 25.0; } @Override public String getDescription() { return super.getDescription() + ", 快递运输"; } }

2.4 第四步:应用观察者模式实现事件通知

java

// 观察者模式:订单状态变更通知 public interface OrderObserver { void update(OrderEvent event); } public interface OrderSubject { void registerObserver(OrderObserver observer); void removeObserver(OrderObserver observer); void notifyObservers(); } public class Order implements OrderSubject { private String orderId; private OrderStatus status; private List<OrderObserver> observers = new ArrayList<>(); @Override public void registerObserver(OrderObserver observer) { observers.add(observer); } @Override public void removeObserver(OrderObserver observer) { observers.remove(observer); } @Override public void notifyObservers() { OrderEvent event = new OrderEvent(this.orderId, this.status); for (OrderObserver observer : observers) { observer.update(event); } } public void setStatus(OrderStatus status) { this.status = status; notifyObservers(); } } // 具体观察者 public class EmailNotificationObserver implements OrderObserver { @Override public void update(OrderEvent event) { System.out.println("发送邮件通知: 订单 " + event.getOrderId() + " 状态变更为 " + event.getStatus()); } } public class InventoryUpdateObserver implements OrderObserver { @Override public void update(OrderEvent event) { if (event.getStatus() == OrderStatus.SHIPPED) { System.out.println("更新库存: 订单 " + event.getOrderId() + " 已发货"); } } }

2.5 第五步:应用工厂模式创建对象

java

// 工厂模式:封装对象创建逻辑 public interface OrderFactory { Order createOrder(String orderId, Customer customer); } public class RegularOrderFactory implements OrderFactory { @Override public Order createOrder(String orderId, Customer customer) { Order order = new Order(); order.setOrderId(orderId); order.setCustomer(customer); order.setType(OrderType.REGULAR); return order; } } public class VIPOrderFactory implements OrderFactory { @Override public Order createOrder(String orderId, Customer customer) { Order order = new Order(); order.setOrderId(orderId); order.setCustomer(customer); order.setType(OrderType.VIP); order.setPriority(true); return order; } } public class OrderFactoryProvider { public static OrderFactory getFactory(CustomerType customerType) { switch (customerType) { case VIP: return new VIPOrderFactory(); case REGULAR: return new RegularOrderFactory(); default: throw new IllegalArgumentException("未知的客户类型"); } } }

第三部分:重构后的完整代码结构

java

// 重构后的主处理器 public class OrderProcessor { private OrderValidator validator; private PriceCalculator priceCalculator; private NotificationService notificationService; private OrderRepository orderRepository; public OrderProcessor() { this.validator = new OrderValidator(); this.priceCalculator = new PriceCalculator(); this.notificationService = new NotificationService(); this.orderRepository = new OrderRepository(); } public void processOrder(OrderRequest request) { // 1. 验证 if (!validator.validateOrder(request.getOrderId())) { throw new IllegalArgumentException("订单无效"); } // 2. 创建订单对象 OrderFactory factory = OrderFactoryProvider.getFactory(request.getCustomerType()); Order order = factory.createOrder(request.getOrderId(), request.getCustomer()); // 3. 计算价格 DiscountStrategy discountStrategy = createDiscountStrategy(request); List<OrderDecorator> decorators = createDecorators(request); double finalPrice = priceCalculator.calculatePrice( request.getOrderId(), discountStrategy, decorators ); order.setTotalPrice(finalPrice); // 4. 保存订单 orderRepository.save(order); // 5. 注册观察者 registerObservers(order); // 6. 状态变更触发通知 order.setStatus(OrderStatus.PROCESSING); // 7. 发送特定通知 notificationService.sendNotification(request.getOrderId(), request.getCustomerType()); } private DiscountStrategy createDiscountStrategy(OrderRequest request) { if (request.getDiscountType() == DiscountType.PERCENTAGE) { return new PercentageDiscountStrategy(request.getDiscountValue()); } else if (request.getDiscountType() == DiscountType.FIXED_AMOUNT) { return new FixedAmountDiscountStrategy(request.getDiscountValue()); } return new NoDiscountStrategy(); } private List<OrderDecorator> createDecorators(OrderRequest request) { List<OrderDecorator> decorators = new ArrayList<>(); OrderComponent basicOrder = new BasicOrder(getBasePrice(request.getOrderId())); if (request.isGiftWrap()) { decorators.add(new GiftWrapDecorator(basicOrder)); } if (request.isExpressShipping()) { decorators.add(new ExpressShippingDecorator(basicOrder)); } return decorators; } private void registerObservers(Order order) { order.registerObserver(new EmailNotificationObserver()); order.registerObserver(new InventoryUpdateObserver()); order.registerObserver(new ReportGenerationObserver()); } }

第四部分:重构前后对比分析

4.1 可维护性对比

维度重构前重构后
方法长度80+行10-20行
类职责8+个职责单一职责
修改影响牵一发而动全身局部影响
测试难度难以单元测试易于测试

4.2 扩展性对比

假设需要添加新的折扣类型:

重构前:

java

// 需要修改processOrder方法,添加新的if条件 if (discountType.equals("SEASONAL")) { // 添加新逻辑 }

重构后:

java

// 只需添加新策略类 public class SeasonalDiscountStrategy implements DiscountStrategy { @Override public double applyDiscount(double price) { // 实现季节性折扣 } }

4.3 代码复用性

重构后各组件可独立复用:

  • DiscountStrategy可用于任何需要折扣的场景

  • OrderDecorator可用于任何需要添加额外服务的场景

  • OrderObserver可用于任何需要事件通知的场景

第五部分:重构最佳实践与注意事项

5.1 重构的时机

  1. 三次法则:第三次做类似事情时进行重构

  2. 添加功能时:在添加新功能前改进代码结构

  3. 修复Bug时:理解代码时顺便重构

  4. 代码审查时:审查他人代码时提出重构建议

5.2 重构的安全网

java

// 1. 编写测试覆盖 @Test public void testOrderProcessing() { OrderProcessor processor = new OrderProcessor(); OrderRequest request = createTestRequest(); processor.processOrder(request); // 验证结果 assertOrderSaved(request.getOrderId()); assertNotificationSent(request.getCustomerType()); } // 2. 小步前进,频繁测试 public class RefactoringSession { public void safeRefactor() { // 步骤1: 提取方法 extractMethod(); runTests(); // 步骤2: 移动方法 moveMethodToProperClass(); runTests(); // 步骤3: 引入设计模式 introduceStrategyPattern(); runTests(); } } // 3. 版本控制提交策略 // 每次重构步骤后立即提交,便于回滚

5.3 常见重构手法速查表

重构手法适用场景设计模式结合
提取方法长方法,重复代码策略模式基础
提取类大类,多职责单一职责原则
移动方法方法放在错误类工厂模式准备
替换条件语句复杂switch/if链策略/状态模式
引入参数对象过长参数列表建造者模式

第六部分:设计模式选择指南

6.1 根据问题选择模式

问题类型推荐模式示例
算法变化策略模式折扣计算
对象创建复杂工厂/建造者订单创建
状态变化通知观察者订单状态更新
动态添加功能装饰者订单附加服务
复杂对象结构组合模式购物车
简化接口外观模式支付系统

6.2 模式组合使用示例

java

// 组合使用多个设计模式 public class EnhancedOrderProcessor { // 外观模式:简化复杂子系统调用 public ProcessingResult processEnhancedOrder(EnhancedOrderRequest request) { // 建造者模式:构建复杂对象 Order order = new OrderBuilder() .withId(request.getId()) .withCustomer(request.getCustomer()) .withItems(request.getItems()) .build(); // 策略模式:算法选择 PaymentStrategy paymentStrategy = PaymentStrategyFactory .createStrategy(request.getPaymentMethod()); // 装饰者模式:动态添加功能 OrderComponent decoratedOrder = new BasicOrder(order); if (request.isInsured()) { decoratedOrder = new InsuranceDecorator(decoratedOrder); } // 模板方法模式:固定流程 return processWithTemplate(order, paymentStrategy); } // 模板方法模式:定义算法骨架 protected ProcessingResult processWithTemplate(Order order, PaymentStrategy strategy) { validate(order); double amount = calculateAmount(order); boolean paid = strategy.pay(amount); if (paid) { return confirmOrder(order); } return failOrder(order); } }

第七部分:重构的度量与评估

7.1 代码质量指标

java

// 重构前后的量化对比 public class CodeQualityMetrics { // 圈复杂度:从重构前的15+降低到3-5 public static int calculateCyclomaticComplexity(MethodNode method) { // 实现圈复杂度计算 } // 代码行数:减少30%-50% public static int countLinesOfCode(File javaFile) { // 统计代码行数 } // 类耦合度:降低依赖关系 public static int calculateCoupling(ClassNode clazz) { // 计算耦合度 } // 内聚性:提高相关功能的集中度 public static double calculateCohesion(ClassNode clazz) { // 计算内聚性 } }

7.2 业务价值指标

  1. 缺陷率:重构后缺陷减少40%

  2. 开发速度:新功能开发时间缩短30%

  3. ** onboarding时间**:新成员理解代码时间从2周减少到3天

  4. 部署频率:由于测试更容易,部署频率提高

第八部分:总结与建议

8.1 重构的核心原则

  1. 渐进式改进:小步快跑,持续改进

  2. 测试驱动:无测试,不重构

  3. 保持功能:重构不改变外部行为

  4. 适时停止:达到"足够好"即可

8.2 从新手到专家的路径

text

初级阶段:学习重构手法 ↓ 中级阶段:识别代码坏味道 ↓ 高级阶段:预设计模式应用 ↓ 专家阶段:架构级重构

8.3 工具推荐

  1. IDE重构工具:IntelliJ IDEA、Eclipse的重构功能

  2. 静态分析工具:SonarQube、Checkstyle

  3. 测试工具:JUnit、Mockito

  4. 版本控制:Git(便于回滚)

8.4 最后建议

"重构不是一次性的活动,而是一种持续实践。优秀的代码不是一开始就设计出来的,而是在不断重构中演化出来的。"

记住:最好的重构时机是现在。从小处开始,从最痛的代码开始,逐步培养重构习惯。每一次重构都是对代码质量的投资,最终将带来可维护性、可扩展性和开发效率的显著提升。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 8:07:02

6、Linux命令实用技巧全解析

Linux命令实用技巧全解析 在Linux系统的使用中,掌握各种命令的使用方法和技巧能够极大地提高工作效率。本文将详细介绍一些常用的Linux命令及其应用场景,帮助大家更好地利用Linux系统。 信息搜索与导航命令 在使用Info系统时,我们可以通过一些快捷键来进行文本搜索和获取…

作者头像 李华
网站建设 2026/2/3 11:46:00

使用Docker快速启动EmotiVoice语音合成服务

使用Docker快速启动EmotiVoice语音合成服务 在智能语音内容需求爆发的今天&#xff0c;无论是有声书、游戏NPC对话&#xff0c;还是虚拟主播直播&#xff0c;用户对“听得舒服”的语音质量提出了前所未有的高要求。传统TTS&#xff08;文本转语音&#xff09;系统虽然能完成基…

作者头像 李华
网站建设 2026/2/13 1:50:52

31、《Expect 中 spawn 命令的使用与相关问题处理》

《Expect 中 spawn 命令的使用与相关问题处理》 1. 检查 spawn 的错误 之前的示例都假定 spawn 总是能成功,但实际上并非如此。不过,它通常只在特殊环境或特殊情况下才会失败。下面我们来详细了解如何判断 spawn 是否成功。 spawn 命令通常会返回新生成进程的进程 ID…

作者头像 李华
网站建设 2026/2/7 7:12:18

32、Expect工具的进程与信号处理

Expect工具的进程与信号处理 1. 特殊系统下的Expect使用 幸运的是,某些无法同时运行多个进程的系统越来越少见了。虽然不能在这类系统上充分发挥Expect的全部功能,但每次自动化一个应用程序,仍可以完成一些有用的工作。在安装时,Expect会检测并报告系统是否无法同时生成多…

作者头像 李华
网站建设 2026/2/4 23:41:52

34、《深入理解 interact 命令:功能、模式与匹配机制》

《深入理解 interact 命令:功能、模式与匹配机制》 1. interact 命令概述 interact 命令具有多种强大功能: - 当从用户或派生进程中检测到特定模式时执行相应操作。 - 允许用户多次控制派生进程,之后再将控制权交回脚本以进行进一步自动化交互。 - 抑制部分或全部交互内…

作者头像 李华
网站建设 2026/2/8 6:29:22

38、自动化脚本中的交互控制与后台处理技术

自动化脚本中的交互控制与后台处理技术 在自动化脚本的编写过程中,我们常常需要处理各种复杂的交互场景和后台任务。本文将详细介绍如何使用 Tcl 脚本和 Expect 工具来实现这些功能,包括用户交互、窗口管理、信号处理以及后台任务的执行。 1. 用户交互与窗口管理 在脚本中…

作者头像 李华