开闭原则(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
相关产品推荐
相关产品推荐

