我违反了打开/关闭"原理?

时间:2016-05-04 18:38:09

标签: java oop solid-principles open-closed-principle

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

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

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

1 个答案:

答案 0 :(得分:7)

严格的答案是肯定的; 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.

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