Java中的SOLID原则:从理论到实践完全指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java中的SOLID原则:从理论到实践

\n\n

SOLID是罗伯特·马丁(Bob大叔)提出的面向对象编程的五个基本原则的首字母缩写。这些原则有助于创建灵活、可维护且可扩展的代码。在本文中,我们将通过Java示例逐一分析每个原则,展示如何违反它们,以及如何正确应用。

\n\n

为什么需要SOLID原则?

\n

没有SOLID,代码很快就会变成“意大利面条”。你是否遇到过修改一个类却破坏了其他三个类的情况?或者一个方法做了太多事情?SOLID解决了这些问题。每个原则都是一条规则,使代码:

\n
    \n
  • 对变更具有弹性——新需求不会破坏旧逻辑。
  • \n
  • 易于理解——每个类只负责一件事。
  • \n
  • 可测试——易于编写单元测试。
  • \n
\n\n

1. 单一职责原则 (SRP)

\n

定义:“一个类应该只有一个引起它变化的原因”。

\n

简单来说:一个类应该只做一件事。如果一个类有多个职责,就很难维护。

\n\n

违反SRP(糟糕的代码)

\n
public class OrderService {\n    public void createOrder(Order order) {\n        // 创建订单的逻辑\n        saveToDatabase(order);\n        sendEmailConfirmation(order);\n    }\n\n    private void saveToDatabase(Order order) {\n        // 保存到数据库\n    }\n\n    private void sendEmailConfirmation(Order order) {\n        // 发送邮件\n    }\n}
\n

问题:该类同时负责业务逻辑、数据库操作和发送通知。修改邮件服务将需要修改OrderService。

\n\n

正确的SRP实现

\n
public class OrderService {\n    private final OrderRepository repository;\n    private final EmailService emailService;\n\n    public OrderService(OrderRepository repo, EmailService email) {\n        this.repository = repo;\n        this.emailService = email;\n    }\n\n    public void createOrder(Order order) {\n        repository.save(order);\n        emailService.sendConfirmation(order);\n    }\n}\n\npublic class OrderRepository {\n    public void save(Order order) { /* 数据库逻辑 */ }\n}\n\npublic class EmailService {\n    public void sendConfirmation(Order order) { /* 邮件逻辑 */ }\n}
\n

现在每个类只有一个变更原因。OrderService仅在创建订单的业务流程发生变化时才需要修改。

\n\n

2. 开闭原则 (OCP)

\n

定义:“类应该对扩展开放,对修改关闭”。

\n

这意味着你应该通过新代码添加新功能,而不是修改现有代码。

\n\n

违反OCP(糟糕的代码)

\n
public class AreaCalculator {\n    public double calculateArea(Object shape) {\n        if (shape instanceof Rectangle) {\n            Rectangle r = (Rectangle) shape;\n            return r.width * r.height;\n        } else if (shape instanceof Circle) {\n            Circle c = (Circle) shape;\n            return Math.PI * c.radius * c.radius;\n        }\n        throw new IllegalArgumentException("未知形状");\n    }\n}
\n

要添加三角形,需要修改calculateArea方法——这违反了OCP。

\n\n

正确的OCP实现

\n
public interface Shape {\n    double calculateArea();\n}\n\npublic class Rectangle implements Shape {\n    private double width, height;\n    public Rectangle(double w, double h) { this.width = w; this.height = h; }\n    @Override\n    public double calculateArea() { return width * height; }\n}\n\npublic class Circle implements Shape {\n    private double radius;\n                

博客

书籍推荐