news 2026/7/12 2:10:48

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

作者头像

张小明

前端开发工程师

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/7/7 1:51:06

47、探索 Expect 在 C 和 C++ 中的应用

探索 Expect 在 C 和 C++ 中的应用 1. 脚本基础操作与练习 在脚本中,有一些基础的操作和初始化代码。例如,改变光标状态的代码如下: # change to busy cursor .list config -cursor watch; update还有一个 update-now 过程,用于触发更新操作: proc update-now {} …

作者头像 李华
网站建设 2026/7/10 14:47:08

EmotiVoice语音合成模型的版权归属与衍生作品声明

EmotiVoice语音合成模型的版权归属与衍生作品声明 在虚拟偶像直播中突然听到一个熟悉的声音——像极了某位明星&#xff0c;但又带着一丝“机械感”&#xff1b;在有声读物里&#xff0c;不同角色用截然不同的音色演绎剧情&#xff0c;而这些声音可能只来自同一个配音员的几秒钟…

作者头像 李华
网站建设 2026/7/8 19:21:11

LobeChat雪崩效应防护措施

LobeChat雪崩效应防护措施 在AI应用快速落地的今天&#xff0c;一个看似简单的聊天界面背后&#xff0c;往往承载着复杂的系统交互与高并发压力。LobeChat 作为一款开源、现代化的智能对话前端&#xff0c;支持接入 GPT、Claude、Llama 等多种大模型&#xff0c;正被广泛用于构…

作者头像 李华
网站建设 2026/7/10 8:20:42

EmotiVoice能否模拟方言发音?测试结果来了

EmotiVoice能否模拟方言发音&#xff1f;测试结果来了 在短视频平台用四川话讲段子的虚拟主播、能说粤语的智能客服、会用上海话讲故事的儿童有声读物——这些曾经依赖真人配音的场景&#xff0c;如今正被AI语音合成技术悄然改变。而像EmotiVoice这样的开源TTS引擎&#xff0c;…

作者头像 李华
网站建设 2026/7/9 11:06:53

EmotiVoice语音合成结果主观评价问卷设计参考

EmotiVoice语音合成结果主观评价问卷设计参考 在虚拟助手越来越“懂人心”、数字人开始拥有情绪起伏的今天&#xff0c;语音合成技术早已不再是简单地把文字念出来。用户期待听到的&#xff0c;是能传递情感、带有温度的声音——就像真人对话那样自然、生动。而开源TTS引擎 Emo…

作者头像 李华
网站建设 2026/7/10 0:12:30

42、C++与汇编语言的链接及优化实战

C++与汇编语言的链接及优化实战 1. C++与汇编程序链接基础 在将单独汇编的ASM模块集成到C++项目时,需要把汇编器生成的目标文件添加到C++项目中。接着从菜单调用MAKE或BUILD命令,该命令会编译CPP文件,若没有错误,就会链接两个目标模块以生成可执行程序。这里建议将CPP源文…

作者头像 李华