首页 文章

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

提问于
浏览
4

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

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

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

1 回答

  • 6

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

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

相关问题