Open/Closed原理查询

Open/Closed principle query

只是一个快速的,所以遵循开闭原则,如果你有一个像这样的 class:

public class Employee extends Person {
    int age;
    String name;

    Employee(int age, String name) {
        super(age, name)
    }
    
    // Getters and setters follow
}

如果你想添加一个额外的字段,比方说一个地址,这不会违反 Open/Closed 原则吗?

很好奇如果您这样做违反了该原则,您将如何创建 class 来解决此问题?

谢谢

简短的回答是“是”。这将违反 OCP。因此,为了回答您的问题(您将如何创建 class 来解决此问题),让我们先看看 OCP 是什么:

Open/Closed原理

OCP 声明软件实体(classes、模块、功能等)应该对扩展开放,但对修改关闭.

你清楚地理解了最后一部分,但你似乎错过了第一部分。同样,对您的问题的简短回答是简单地 扩展 您原来的 class.

public class Person {
   int age;
   String name;
   // rest of class omitted
}

// This class already obeyed OCP by extending Person and adding new attributes and behaviors (took the liberty to change your original class for a good reason - See Person class)
public class Employee extends Person {
   String empID;
   // Rest of the class omitted
}

// Simply add one more (corny class name, sorry)
public class AddressableEmployee extends Employee {
   private String address;
   // Rest of the class omitted
}

这是添加新功能时如何遵守 OCP。显然,如果滥用它,会导致 class 爆炸,这也很糟糕。作为开发人员(和设计人员),您必须权衡盲目地尊重这一原则与创建深层层次链。

要记住的是,OCP(与 SOLID 的其余部分一样)只是建议。最后,如果您发现自己处于这种情况,这可能表明您做出了草率的设计决策(直接实施而没有花足够的时间来巩固您的设计)。因此,与其草率地做出另一个实施决定,不如停下来考虑重新设计您最初创建的内容(即考虑组合而不是继承)。

简短的回答是“是”。 @hfontanez 对 OCP 进行了很好的高级介绍,您会在 SO 上看到大多数与 OCP 相关的答案。

但长答案是“不”。因为 OCP 在这里不适用。
要了解什么样的场景我们需要担心OCP,我们必须从合适的编程范式开始。 OCP 与所有 SOLID 原则一样,是面向对象的。它适用于面向对象的代码。

Employee 不是对象,在 OO 的意义上,因为对象有行为。 Employee 是一种数据结构:它纯粹是状态的表示。数据结构是过程式编程和函数式编程的基础,但不是 OO。尝试将 OCP 应用于 Employee 让我们从一开始就走上了错误的轨道,因为我们处于错误的范式中。

解决范式问题似乎微不足道。我们可以在 Employee 中实现一个 doWork() 方法,然后我们就有了一些行为,对吧?但这是 SOLID 原则开始相互作用的地方。因为谁会调用 doWork() 方法?当然不是 Employee 模块之外的任何客户端!毕竟,Employee 是一个具体的实现,依赖倒置原则规定依赖于抽象,而不是具体。

同样,我们可能会找到一个简单的解决方案。将 doWork() 方法提取到由 Employee 实现的接口。现在客户可以在遵守 DIP 的同时调用它。 (并且由于我们正在考虑 SOLID 原则的交互,还假设 doWork() 的实现遵守其抽象声明的约定,因此我们不会违反 LSP。)

当然现在 OCP 适用于 Employee,对吧?它同时具有状态和行为(使其成为成熟的 OO 对象),并且通过适当的抽象公开其行为。但是 OCP 仍然不适用...因为 Employee 现在是一个实现细节。根据 OCP,“封闭”的定义包括发布供客户使用(即 public)。实现细节不是此定义的一部分。

因此通过结合 SOLID 原则,我们得出了一个重要的结论。

The OCP applies strictly to the public, abstract, API of an object-oriented application or library.

随意编辑您的实施细节。 OCP不介意。