开放封闭原则 - 重构以基于新功能创建基类

时间:2014-04-30 19:16:39

标签: solid-principles open-closed-principle

因此,当编写原始代码时,只需要说LabTest类。但现在说我们有新的要求添加说RadiologyTest,EKGTest等。

这些类有很多共同之处,因此有一个基类是有道理的。

但这意味着必须修改LabTest类,让我们说它的界面将保持原样,换句话说,LabTest类的消费者不需要改变。

这违反了开放封闭原则的原则吗? (正在修改LabTest)。

4 个答案:

答案 0 :(得分:2)

我认为您可以从两个角度来看待它:现有要求新要求

如果现有的要求没有涵盖这些变更的需要,那么我会说,根据这些要求,LabTest没有违反OCP。

根据新要求,您需要添加不适合LabTest实现的功能。将其添加到OCP会违反SRP。这些要求现在会创建一个新的更改向量,这将迫使您重构LabTest以使其保持OCP。如果您未能重构LabTest,则会违反SRP和OCP。重构时,请记住您创建或修改的任何类中的新更改向量。

答案 1 :(得分:1)

  

这些类有很多共同之处,因此有一个基类是有道理的。

我认为您可能违反了SRP。毕竟,如果每个班级完成一项任务,两个或两个以上的课程如何相似?如果有任务他们都做同样的事情,那么这是一个单独的任务,应由另一个班级完成。

所以我想说,首先将重构LabTest放入其组成部分(希望你有单元测试!)。然后当你来写RadiologyTestEKGTest时,他们可以重复使用对他们有意义的部分。这也称为继承的组合。

但无论你做什么,都要在客户端使用这些类的接口。不要强迫关注者使用您的基类添加扩展名。

答案 2 :(得分:1)

我可能会因为这个答案而被烧伤,但无论如何都会陷入困境。 在我看来(IMO),OCP不能像纯粹主义者那样遵循其他原则,如SRP,DIP或ISP。

如果需求发生变化,您必须将类的职责更改为其对域模型的表示形式的真实性,那么我们必须更改该类。

IMO,OCP阻止我们重新分解代码以跟随系统的发展。

如果我错了,请纠正我。

<强>更新 经过进一步的研究,这就是我的想法: 可以说,我已经在单元级别和集成级别上进行了自动化测试,然后IMO我们应该重新设计完整的系统以适应新的模型,OCP就在这里。 IMO,系统演变的目标始终是避免黑客攻击(不改变LabTest类和相应的DB表,以免破坏旧代码[不违反OCP],并使用LabTest存储EKGTest的常用数据并在EKGTest中使用LabTest或继承自LabTest的EKGTest将成为一个黑客,IMO将会并且使系统尽可能准确地表示其模型。

答案 3 :(得分:1)

我认为开放封闭原则(无论如何,鲍勃叔叔和Bertrand Meyers所描述的)并不是永远不会修改类(如果软件永远不会改变它也可能是硬件)。

&安培;在你自己的情况下,我认为你没有违反OCP,因为你提到你对你的所有用途都取决于LabTest的抽象,而不是RadiologyTest的实现。 / p>

Uncle Bob's introductory paper开始,他有一个DrawAllShapes类的示例,如果设计为OCP,则每次将Shape的新子类添加到系统时都不需要更改。关于你应用它的级别,鲍勃叔叔说 -

  

应该清楚的是,没有重要的计划可以100%关闭。对于   例如,考虑一下DrawAllShapes函数会发生什么   清单2,如果我们决定在任何Circles之前绘制所有Squares   DrawAllShapes。 {{1}}函数未针对更改关闭   像这样。一般来说,无论模块是多么“封闭”,都会有   永远都是某种不被关闭的变化。

     

由于关闭无法完成,因此必须具有战略意义。那就是   设计师必须选择哪种变化来关闭他的   设计。

我不会将“关闭修改”视为“不要重构”,更多的是你应该设计你的类,使其他类不能进行会影响你的修改 - 例如应用基本的OO东西 - 通过getter / setter&amp; amp;封装私有成员变量。