我是不是违反了“开放/封闭”原则?
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);
然后,您可以为要对数据执行的每个不同计算创建一个计算类(例如:MeanCalculation
、StdDevCalculation
等)。如果您想要一个新的计算(例如:MedianCalculation
),您可以在不修改此区域中的任何其他代码的情况下进行此操作(对修改关闭,对扩展开放;符合 OCP)。最终结果如下:
Measurements values = ...
Number mean = values.performCalculation(new MeanCalculation());
Number SD = values.performCalculation(new StdDevCalculation());
// etc.
我并不是说这是针对您的具体情况的最佳方法(或者甚至是该方法的最佳实施);你需要自己回答。但我希望这个答案能够为这个问题提供一个体面的外部视角。
【讨论】:
以上是关于我是不是违反了“开放/封闭”原则?的主要内容,如果未能解决你的问题,请参考以下文章