我是不是违反了“开放/封闭”原则?

Posted

技术标签:

【中文标题】我是不是违反了“开放/封闭”原则?【英文标题】:Am I violating the "open/closed" principle?我是否违反了“开放/封闭”原则? 【发布时间】:2016-05-04 18:38:08 【问题描述】:

场景:我将一些信息(例如双精度数组)存储在类字段中(例如字段 Measurements,类中的整数数组 MeasureData)。现在我想使用这些数据来执行一些计算(例如计算数组的算术平均值、最大值和最小值)。目前,我不知道将来是否需要对这些数据进行任何其他操作(例如,也许我需要获得标准差、总和或其他)。我会有很多MeasureData 类型的对象。

解决方案:我可以编写一个类Calculator,将其声明为final,使用私有构造函数并使用几个静态方法来执行我需要的计算。这似乎是有道理的,因为Calculator 充当实用程序类,没有任何字段,很像标准的Math 类。

问题:如果几个月后我需要进行任何其他计算,我将需要在Calculator 中编写另一个静态方法。这是否意味着违反了开闭原则(毕竟我是在修改Calculator类的实现)?

【问题讨论】:

我记得 Bob 叔叔说过 SOLID 原则是重构工具(不记得是在演讲还是在帖子中),但如果可以的话,我会尝试挖掘一个链接——基本上,使用 OCP,不必(太担心)以后需要更改类,但如果您确实需要更改类,请以支持 OCP 未来更改的方式进行方式。另外,here's a useful blog post from him on same 【参考方案1】:

严格的答案是肯定的; OCP 声明一个类对扩展开放但对修改关闭。您将修改 Calculator,因此违反了 OCP(正如您已经得出的结论)。

这导致两点:

首先,在这种情况下,违反 OCP 是否很重要?您正在添加更改 Calculator 以向其添加新方法。 Calculator 是一个静态帮助类,用于从对象中获取有意义的数据。添加新方法(例如计算 SD)不会影响其中的任何其他操作。有了正确的实现,真的有办法添加这个方法会危及你的项目吗?

其次,如果您觉得 OCP 违规是不可接受的,那么这是一个教科书示例,说明可以使用 Strategy Pattern。考虑:

Measurements.Java

public class Measurements 
    private int[] data;

    public Measurements(int[] data) 
        this.data = data;
    

    public Number performCalculation(Calculation c) 
        return c.performCalculation(data);
    

Calculation.java

public interface Calculation 
    Number performCalculation(int[] data);

然后,您可以为要对数据执行的每个不同计算创建一个计算类(例如:MeanCalculationStdDevCalculation 等)。如果您想要一个新的计算(例如:MedianCalculation),您可以在不修改此区域中的任何其他代码的情况下进行此操作(对修改关闭,对扩展开放;符合 OCP)。最终结果如下:

Measurements values = ...
Number mean = values.performCalculation(new MeanCalculation());
Number SD = values.performCalculation(new StdDevCalculation());
// etc.

我并不是说这是针对您的具体情况的最佳方法(或者甚至是该方法的最佳实施);你需要自己回答。但我希望这个答案能够为这个问题提供一个体面的外部视角。

【讨论】:

以上是关于我是不是违反了“开放/封闭”原则?的主要内容,如果未能解决你的问题,请参考以下文章

检查异常是不是违反了开放封闭原则?

Objective C 类别 vs 开放/封闭原则

开放封闭原则

开放/封闭原则的问题?

开放封闭原则|SOLID as a rock

设计模式--开放封闭原则