SOLID原则在Java中:从理论到整洁代码
每个Java开发者迟早都会面临"脏代码"的问题:类试图完成所有事情、僵硬的依赖关系,以及无法在不破坏现有逻辑的情况下进行扩展。这时,SOLID原则就来拯救你了——这是由Robert Martin(Uncle Bob)提出的五个面向对象设计基本原则。在本文中,我们将通过Java示例逐一剖析每个原则的实践应用,让你的代码变得灵活、可测试且易于维护。
1. 单一职责原则(SRP)
核心思想:"一个类应该只有一个引起变化的原因。"换句话说,一个类应该负责一个明确定义的任务。
违反SRP的示例
考虑OrderService类,它同时处理价格计算、数据库保存和邮件发送:
public class OrderService { public void processOrder(Order order) { // 1. 价格计算 double total = order.getItems().stream() .mapToDouble(Item::getPrice) .sum();
// 2. 保存到数据库 Database.save(order);
// 3. 发送通知 EmailService.send("订单已创建,金额:" + total); }}问题:更改邮件发送逻辑或保存方法将迫使OrderService发生更改。这违反了SRP。
基于SRP的重构
我们将职责拆分为三个独立的类:
public class PriceCalculator { public double calculateTotal(Order order) { return order.getItems().stream() .mapToDouble(Item::getPrice) .sum(); }}
public class OrderRepository { public void save(Order order) { Database.save(order); }}
public class NotificationService { public void sendConfirmation(Order order) { EmailService.send("订单已创建,金额:" + order.getTotal()); }}
// 客户端代码public class OrderProcessor { private PriceCalculator calculator; private OrderRepository repository; private NotificationService notifier;
public void processOrder(Order order) { double total = calculator.calculateTotal(order); order.setTotal(total); repository.save(order); notifier.sendConfirmation(order); }}结果:每个类只有一个引起变化的原因。代码变得模块化且可测试。
2. 开闭原则(OCP)
核心思想:"软件实体应该对扩展开放,对修改关闭。"新功能通过扩展而非修改现有代码来添加。
违反OCP的示例
想象一个折扣系统,其中每种新的折扣类型都需要修改applyDiscount方法:
public class DiscountService { public double applyDiscount(String type, double price) { if (type.equals("SUMMER")) { return price * 0.9; } else if (type.equals("VIP")) { return price * 0.8; } // 添加新类型 → 修改该类 return price; }}通过多态实现解决方案
我们使用接口和不同的实现:
public interface Discount { double apply(double price);}
public class SummerDiscount implements Discount { @Override public double apply(double price) { return price * 0.9; }}
public class VipDiscount implements Discount { @Override public double apply(double price) { return price * 0.8; }}
// 新类型——只需一个新类