You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

理解开闭原则:求非平凡Java类反例

违反开闭原则的Java示例及分析

反例代码:硬编码支付逻辑的订单处理器

假设我们有一个处理订单支付的类,它直接把所有支付方式的逻辑写在了同一个方法里:

public class OrderProcessor {
    public void processPayment(Order order, String paymentType) {
        if ("ALIPAY".equals(paymentType)) {
            // 支付宝支付逻辑:调用支付宝SDK、验证签名、处理回调等
            System.out.println("处理支付宝支付:订单号" + order.getId());
            // 省略具体实现细节
        } else if ("WECHAT".equals(paymentType)) {
            // 微信支付逻辑:调用微信支付API、生成预支付单等
            System.out.println("处理微信支付:订单号" + order.getId());
            // 省略具体实现细节
        }
        // 新增支付方式时,必须在这里加新的else if分支
    }
}

class Order {
    private String id;
    public Order(String id) {
        this.id = id;
    }
    public String getId() {
        return id;
    }
}

违反开闭原则的原因

开闭原则要求软件实体(类、模块、函数等)对扩展开放,对修改关闭。这个OrderProcessor类完全违反了这一点:

  • 新增支付方式(比如银联支付、Apple Pay)时,必须直接修改processPayment方法的代码,添加新的条件分支
  • 它没有提供任何扩展点,所有支付逻辑都耦合在同一个类中,无法通过新增类来扩展功能

具体弊端

  • 回归风险高:修改原有方法时,可能误破坏已有支付方式的逻辑,比如改坏支付宝的签名验证规则,导致线上支付故障。每次新增功能都要重新测试所有已有支付方式,测试成本陡增。
  • 违反单一职责:OrderProcessor既负责订单支付的流程控制,又要实现每种支付方式的具体逻辑,职责混杂,代码臃肿,后期维护难度极大。
  • 耦合度极高:支付方式的变化直接绑定到OrderProcessor的代码,一旦某个支付方式的API更新,必须修改这个核心类,牵一发而动全身。
  • 扩展性差:如果要支持10种支付方式,processPayment方法会变成一个巨型条件判断块,可读性和可维护性完全丧失。

符合开闭原则的改进方案

通过策略模式重构,抽象出支付处理的接口,让每种支付方式成为独立的实现类:

// 抽象支付处理器接口(扩展点)
public interface PaymentProcessor {
    void process(Order order);
}

// 支付宝支付实现
public class AlipayProcessor implements PaymentProcessor {
    @Override
    public void process(Order order) {
        System.out.println("处理支付宝支付:订单号" + order.getId());
        // 具体支付宝逻辑
    }
}

// 微信支付实现
public class WechatProcessor implements PaymentProcessor {
    @Override
    public void process(Order order) {
        System.out.println("处理微信支付:订单号" + order.getId());
        // 具体微信逻辑
    }
}

// 订单处理器依赖抽象接口,无需修改即可扩展
public class OrderProcessor {
    private PaymentProcessor paymentProcessor;

    public OrderProcessor(PaymentProcessor paymentProcessor) {
        this.paymentProcessor = paymentProcessor;
    }

    public void processPayment(Order order) {
        paymentProcessor.process(order);
    }
}

重构后,新增银联支付只需要创建UnionPayProcessor implements PaymentProcessor,完全不需要修改OrderProcessor的代码,真正做到了对扩展开放,对修改关闭。

内容的提问来源于stack exchange,提问作者djna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:07:23