Java中的SOLID原则:理论与实践进阶

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

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

开始课程

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



SOLID原则是面向对象设计的基石,帮助开发者创建易于变更、易于测试且可扩展的代码。对于Java开发者而言,在高级层面理解这些原则,不仅仅是知道定义,更要能在遗留代码中发现其违反之处,并应用设计模式进行重构。本文将深入剖析每个原则,重点关注复杂但典型的场景。



1. 单一职责原则(SRP):职责与内聚的界限



理论:一个类应该只有一个引起变化的原因。在实践中,这意味着一个类应负责程序功能的一个部分。



高级实践:SRP的违反往往不表现为逻辑的明显混合,而是职责的“模糊化”。考虑一个处理报表的类示例:



// 违反SRP:该类同时处理数据、格式化和发送public class ReportService {    public void generateReport(List<Data> data) {        // 计算逻辑        Map<String, Integer> aggregated = aggregate(data);        // 格式化(HTML)        String html = formatToHtml(aggregated);        // 通过邮件发送        sendEmail(html, "admin@example.com");    }

private Map<String, Integer> aggregate(List<Data> data) { // ... return new HashMap<>(); }

private String formatToHtml(Map<String, Integer> data) { // ... return "<html>...</html>"; }

private void sendEmail(String content, String to) { // ... }}


问题:如果报表格式改变(需要PDF而非HTML),必须修改此类。如果发送方式改变(从邮件改为Telegram),同样需要修改。解决方案——拆分为三个类:



public class ReportAggregator {    public Map<String, Integer> aggregate(List<Data> data) { ... }}

public class HtmlReportFormatter { public String format(Map<String, Integer> data) { ... }}

public class EmailSender { public void send(String content, String to) { ... }}

// 在服务中进行组合public class ReportGenerationFacade { private ReportAggregator aggregator; private HtmlReportFormatter formatter; private EmailSender sender;

public void generateAndSend(List<Data> data) { var aggregated = aggregator.aggregate(data); var html = formatter.format(aggregated); sender.send(html, "admin@example.com"); }}


2. 开闭原则(OCP):通过抽象实现扩展的艺术



理论:类应对扩展开放,对修改关闭。



高级实践:典型的违反是使用if-else或switch链处理不同类型的对象。高级做法是使用策略模式或模板方法模式结合多态。



// 违反OCP:添加新的支付类型时需要修改类public class PaymentProcessor {    public void processPayment(String type, double amount) {        if ("CREDIT_CARD".equals(type)) {            // 信用卡逻辑        } else if ("PAYPAL".equals(type)) {            // PayPal逻辑        } else if ("BITCOIN".equals(type)) {            // 比特币逻辑        }    }}


通过接口和工厂进行修正:



public interface PaymentMethod {    void pay(double amount);}

public class CreditCardPayment implements PaymentMethod { public void pay(double amount) { ... }}

public class PayPalPayment implements PaymentMethod

博客

书籍推荐