场景:我在类字段中存储了一些信息(例如,双精度数组)(比如字段Measurements
,类MeasureData
中的整数数组)。现在我想使用这些数据来执行一些计算(例如计算数组的算术平均值,最大值和最小值)。目前,我不知道将来我是否需要对这些数据进行任何其他操作(例如,我可能需要获得标准偏差,总和或其他)。我会有许多MeasureData
类型的对象。
解决方案:我可以编写一个类Calculator
,声明它是final,使用私有构造函数并使用几个静态方法来执行我需要的计算。这似乎是有道理的,因为Calculator
充当实用程序类,没有任何字段,就像标准的Math
类一样。
问题:如果在几个月内,我需要进行任何其他计算,我将需要在Calculator
中编写另一个静态方法。这是否意味着违反开放/封闭原则(毕竟,我正在修改类Calculator
的实现)?
答案 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);
}
然后,您可以为要对数据执行的每个不同计算创建计算类(例如:MeanCalculation
,StdDevCalculation
等。如果您想要一个新的计算(例如:MedianCalculation
),您可以在不修改此区域中的任何其他代码的情况下进行此操作(关闭以进行修改,打开以进行扩展;符合OCP标准)。最终结果如下:
Measurements values = ...
Number mean = values.performCalculation(new MeanCalculation());
Number SD = values.performCalculation(new StdDevCalculation());
// etc.
我并不是说这是针对您具体案例的最佳方法(或者甚至是最佳实施方法);你需要自己回答这个问题。但我希望这个答案能为这个问题提供一个体面的外部视角。