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

开闭原则(Open-closed principle)与DRY原则的冲突疑问

问题:遵循开闭原则新增支付类却存在大量重复代码,是否违反DRY原则?

我们的应用最初仅支持一种支付方式,为此定义了Payment接口及其实现类InitialPayment:

interface Payment {
   // 支付相关方法
}

class InitialPayment implements Payment {
   // 初始支付方式的实现逻辑
}

后续产品要求新增另一种支付方式,我们遵循**开闭原则(Open-Closed Principle)**创建了第二个实现类AnotherPayment:

class AnotherPayment implements Payment {
   // 新增支付方式的实现逻辑
}

目前运行正常,但这两个类存在80%的重复逻辑与代码,请问这是否违反了DRY(Don't Repeat Yourself)原则?或是我忽略了什么要点?


回答

这种情况确实违反了DRY原则,而且开闭原则和DRY原则并不冲突,完全可以结合起来做到既符合开闭要求又消除重复代码。

  • 开闭原则的核心是对扩展开放、对修改关闭,你通过新增实现类扩展支付方式的做法是符合这个原则的,但这并不意味着要放任大量重复代码存在。
  • 80%的重复逻辑说明两个支付类在核心流程上高度一致,只是少数环节有差异。这时应该把通用逻辑提取到一个抽象父类(比如AbstractPayment)中,让两个实现类继承这个抽象类,只实现各自差异化的部分。举个例子:
abstract class AbstractPayment implements Payment {
    // 这里放80%的通用重复逻辑,比如参数校验、日志记录、通用流程处理等
    public void commonPaymentProcess() {
        // 通用逻辑的具体实现
    }
}

class InitialPayment extends AbstractPayment {
    // 只写InitialPayment特有的逻辑
}

class AnotherPayment extends AbstractPayment {
    // 只写AnotherPayment特有的逻辑
}
  • 这样调整后,既遵循了开闭原则(后续新增支付方式依然可以通过继承抽象类扩展,不用修改已有代码),又满足了DRY原则(重复代码被统一维护,后续修改通用逻辑只需要改一处)。
  • 你可能陷入了一个误区:觉得“遵循开闭原则就必须每个子类完全独立实现”,但开闭原则禁止的是修改原有功能的逻辑,而重构提取抽象类只是调整代码结构,并没有改变原有支付方式的功能,反而让代码更健壮、更容易维护。

内容的提问来源于stack exchange,提问作者G.Baghashvili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:41:24