我是否违反了 "open/closed" 原则?

Am I violating the "open/closed" principle?

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

类型的对象

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

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

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

这导致两点:

首先,在这种情况下违反 OCP 有什么大不了的吗?您正在附加地更改 Calculator 以向其添加新方法。 Calculator 是一个静态助手 class,用于从您的对象中获取有意义的数据。添加新方法,如计算 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);
}

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

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

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