以下是 Spring 框架中体现的 SOLID 设计模式七大原则 的分类、技术原理及代码示例:
1. 单一职责原则 (Single Responsibility Principle, SRP)
定义:一个类应该只有一个引起它变化的原因。
Spring 实现:通过 @Service
、@Repository
等注解将职责拆分到不同组件。
// 单一职责:用户服务只处理用户相关逻辑
@Service
public class UserService {
public User getUserById(Long id) {
// 查询用户逻辑
return new User();
}
}
// 违反 SRP 的反例:混合订单逻辑
@Service
public class BadUserService {
public User getUserById(Long id) { /* ... */ }
public Order createOrder(User user) { /* ... */ } // 职责不单一
}
2. 开闭原则 (Open-Closed Principle, OCP)
定义:软件实体应对扩展开放,对修改关闭。
Spring 实现:通过 BeanPostProcessor
扩展点实现功能增强,无需修改原有代码。
// 扩展点:自定义 Bean 后置处理器
@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof Loggable) {
System.out.println("Logging initialized for: " + beanName);
}
return bean;
}
}
// 业务代码无需修改即可扩展日志功能
@Service
public class OrderService implements Loggable {
// 原有业务逻辑
}
3. 里氏替换原则 (Liskov Substitution Principle, LSP)
定义:子类必须能够替换其父类而不影响程序正确性。
Spring 实现:通过接口和实现类的继承关系保证替换性。
// 父类接口
public interface PaymentGateway {
boolean pay(double amount);
}
// 子类实现
@Component
public class AlipayGateway implements PaymentGateway {
@Override
public boolean pay(double amount) {
// 支付宝支付逻辑
return true;
}
}
// 客户端代码(可替换为其他实现)
@Service
public class OrderService {
@Autowired
private PaymentGateway paymentGateway; // 依赖接口而非具体实现
public boolean placeOrder(double amount) {
return paymentGateway.pay(amount);
}
}
4. 接口隔离原则 (Interface Segregation Principle, ISP)
定义:客户端不应依赖它不需要的接口。
Spring 实现:通过细粒度接口(如 Runnable
、Callable
)替代臃肿接口。
// 细粒度接口(符合 ISP)
public interface UserQueryService {
User getUserById(Long id);
}
public interface UserCommandService {
void createUser(User user);
void updateUser(User user);
}
// 违反 ISP 的反例:臃肿接口
public interface UserService {
User getUserById(Long id);
void createUser(User user);
void updateUser(User user);
void deleteUser(Long id); // 客户端可能不需要删除功能
}
5. 依赖倒置原则 (Dependency Inversion Principle, DIP)
定义:高层模块不应依赖低层模块,二者都应依赖抽象。
Spring 实现:通过 @Autowired
注入抽象(接口)而非具体实现。
// 抽象层
public interface MessageSender {
void send(String message);
}
// 具体实现
@Component
public class EmailSender implements MessageSender {
@Override
public void send(String message) {
// 发送邮件逻辑
}
}
// 高层模块依赖抽象
@Service
public class NotificationService {
private final MessageSender messageSender;
@Autowired // 注入抽象而非具体实现
public NotificationService(MessageSender messageSender) {
this.messageSender = messageSender;
}
public void notifyUser(String message) {
messageSender.send(message);
}
}
6. 迪米特法则 (Law of Demeter, LoD)
定义:一个对象应对其他对象有尽可能少的了解。
Spring 实现:通过 @Transactional
注解隐藏事务管理细节。
// 业务代码无需了解事务实现细节
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Transactional // 隐藏事务管理逻辑
public void placeOrder(Order order) {
orderRepository.save(order);
// 其他业务逻辑
}
}
// 底层事务管理由 Spring 实现
@Repository
public class OrderRepository {
@Transactional(propagation = Propagation.REQUIRED)
public void save(Order order) {
// 数据库操作
}
}
7. 合成复用原则 (Composite Reuse Principle, CRP)
定义:优先使用对象组合而非类继承。
Spring 实现:通过 @Autowired
组合 Bean 而非继承。
// 通过组合复用功能(符合 CRP)
@Service
public class ReportService {
private final DataExporter dataExporter;
private final EmailService emailService;
@Autowired
public ReportService(DataExporter dataExporter, EmailService emailService) {
this.dataExporter = dataExporter;
this.emailService = emailService;
}
public void generateAndSendReport() {
dataExporter.export();
emailService.send("Report generated");
}
}
// 违反 CRP 的反例:通过继承复用
@Service
public class BadReportService extends DataExporter {
@Autowired
private EmailService emailService;
public void generateAndSendReport() {
super.export();
emailService.send("Report generated");
}
}
总结
Spring 框架通过以下方式践行 SOLID 原则:
- SRP:通过注解划分职责(
@Service
、@Repository
)。 - OCP:通过
BeanPostProcessor
扩展点实现无侵入式增强。 - LSP:通过接口和实现类的继承关系保证替换性。
- ISP:通过细粒度接口(如
Runnable
)替代臃肿接口。 - DIP:通过依赖注入(
@Autowired
)解耦高层与底层模块。 - LoD:通过
@Transactional
隐藏事务管理细节。 - CRP:通过组合 Bean(
@Autowired
)而非继承实现复用。