因此,当编写原始代码时,只需要说LabTest类。但现在说我们有新的要求添加说RadiologyTest,EKGTest等。
这些类有很多共同之处,因此有一个基类是有道理的。
但这意味着必须修改LabTest类,让我们说它的界面将保持原样,换句话说,LabTest类的消费者不需要改变。
这违反了开放封闭原则的原则吗? (正在修改LabTest)。
答案 0 :(得分:2)
我认为您可以从两个角度来看待它:现有要求和新要求。
如果现有的要求没有涵盖这些变更的需要,那么我会说,根据这些要求,LabTest没有违反OCP。
根据新要求,您需要添加不适合LabTest实现的功能。将其添加到OCP会违反SRP。这些要求现在会创建一个新的更改向量,这将迫使您重构LabTest以使其保持OCP。如果您未能重构LabTest,则会违反SRP和OCP。重构时,请记住您创建或修改的任何类中的新更改向量。
答案 1 :(得分:1)
这些类有很多共同之处,因此有一个基类是有道理的。
我认为您可能违反了SRP。毕竟,如果每个班级完成一项任务,两个或两个以上的课程如何相似?如果有任务他们都做同样的事情,那么这是一个单独的任务,应由另一个班级完成。
所以我想说,首先将重构LabTest
放入其组成部分(希望你有单元测试!)。然后当你来写RadiologyTest
,EKGTest
时,他们可以重复使用对他们有意义的部分。这也称为继承的组合。
但无论你做什么,都要在客户端使用这些类的接口。不要强迫关注者使用您的基类添加扩展名。
答案 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;封装私有成员变量。