面向对象设计的 SOLID 原则
SOLID 原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则
单一职责原则 (Single Responsibility Principle, SRP)
每个类应该只有一个引起它变化的原因,即一个类只负责一项职责。
开闭原则 (Open-Closed Principle, OCP)
软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
里氏替换原则 (Liskov Substitution Principle, LSP)
子类型必须能够替换它们的基类型,而不影响程序的正确性。
接口隔离原则 (Interface Segregation Principle, ISP)
客户端不应该被迫依赖它们不使用的接口,应该将臃肿的接口拆分成更小更具体的接口。
依赖倒置原则 (Dependency Inversion Principle, DIP)
高层模块不应该依赖低层模块,两者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。
用一个实际的案例,贯穿解释 SOLID 原则
电商订单系统案例解析 SOLID 原则
案例背景
我们设计一个电商平台的订单处理系统,通过这个案例来展示如何应用 SOLID 原则。
1. 单一职责原则应用
原始设计问题
class OrderProcessor {
public void process(Order order) {
// 验证订单
// 计算价格
// 保存到数据库
// 发送邮件通知
}
}
重构后设计
class OrderValidator {
public void validate(Order order) { /*...*/ }
}
class PriceCalculator {
public void calculate(Order order) { /*...*/ }
}
class OrderRepository {
public void save(Order order) { /*...*/ }
}
class NotificationService {
public void sendEmail(Order order) { /*...*/ }
}
每个类只负责一个明确的功能,修改验证逻辑不会影响价格计算等其他功能。
2. 开闭原则应用
支付方式扩展
interface PaymentMethod {
void processPayment(double amount);
}
class CreditCardPayment implements PaymentMethod {
public void processPayment(double amount) { /*...*/ }
}
class PayPalPayment implements PaymentMethod {
public void processPayment(double amount) { /*...*/ }
}
class PaymentProcessor {
public void process(PaymentMethod method, double amount) {
method.processPayment(amount);
}
}
当需要新增支付方式 (如加密货币) 时,只需新增实现类而不需修改现有代码。
3. 里氏替换原则应用
折扣策略设计
abstract class DiscountStrategy {
abstract double applyDiscount(double originalPrice);
}
class PercentageDiscount extends DiscountStrategy {
public double applyDiscount(double originalPrice) {
return originalPrice * 0.9; // 10%折扣
}
}
class FixedAmountDiscount extends DiscountStrategy {
public double applyDiscount(double originalPrice) {
return originalPrice - 50; // 固定减50
}
}
任何 DiscountStrategy 的子类都可以互换使用,不会破坏原有逻辑。
4. 接口隔离原则应用
订单接口拆分
// 不好的设计
interface OrderOperations {
void createOrder();
void updateOrder();
void deleteOrder();
void printInvoice();
void generateReport();
}
// 好的设计
interface OrderCRUD {
void createOrder();
void updateOrder();
void deleteOrder();
}
interface OrderPrinting {
void printInvoice();
}
interface OrderReporting {
void generateReport();
}
客户端只需依赖它们实际需要的接口,避免被迫实现不需要的方法。
5. 依赖倒置原则应用
订单存储设计
interface OrderStorage {
void save(Order order);
Order findById(String id);
}
class DatabaseOrderStorage implements OrderStorage {
public void save(Order order) { /*...*/ }
public Order findById(String id) { /*...*/ }
}
class OrderService {
private OrderStorage storage;
public OrderService(OrderStorage storage) {
this.storage = storage;
}
public void processOrder(Order order) {
storage.save(order);
}
}
高层 OrderService 依赖抽象的 OrderStorage 接口,而不是具体的数据库实现,便于切换存储方式。
综合应用效果
通过遵循 SOLID 原则,我们的订单系统获得了:
- 更清晰的职责划分
- 更好的可扩展性
- 更强的可维护性
- 更高的代码复用率
- 更松散的耦合度
这些原则共同作用,使系统能够更灵活地应对需求变化,同时保持代码的整洁和可理解性。