1

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

这些类有很多共同点,因此有一个基类是有意义的。

但这意味着 LabTest 类将不得不被修改,可以说它的界面将保持与以前相同,换句话说 LabTest 类的消费者将不需要更改。

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

4

4 回答 4

2

我想你可以从两个角度来看:现有需求新需求

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

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

于 2014-05-01T17:55:33.203 回答
1

我认为开闭原则(正如鲍勃叔叔所概述的那样,与伯特兰迈耶斯相比)不是关于永远不修改类(如果软件永远不会改变它也可能是硬件)。

LabTest& 在您自己的情况下,我不认为您违反了 OCP,因为您已经提到您对类的所有使用都取决于RadiologyTest.

Bob 叔叔的介绍性论文中,他有一个DrawAllShapes类的示例,如果设计为 OCP,则每次将新的子类Shape添加到系统时都不需要更改。关于你应用它的级别,鲍勃叔叔说——</p>

应该清楚的是,没有重要的程序可以 100% 关闭。例如,考虑DrawAllShapes如果我们决定 allCircles应该在 any 之前绘制,清单 2 中的函数会发生什么 Squares。对于这样的更改,该DrawAllShapes功能不会关闭。一般来说,无论一个模块多么“封闭”,总会有某种变化,它不会被封闭。

由于关闭不可能完全,它必须是战略性的。也就是说,设计者必须选择关闭他的设计的变化类型。

我不会将“关闭以供修改”阅读为“不要重构”,更多的是您应该以其他类无法进行会影响您的修改的方式设计您的类 - 例如应用基本的 OO 东西 - 封装通过 getter/setter 和私有成员变量。

于 2014-05-11T18:19:52.410 回答
1

这些类有很多共同点,因此有一个基类是有意义的。

我认为您可能违反了 SRP。毕竟,如果每个班级都做一个任务,那么两个或更多怎么会如此相似呢?如果有一个任务他们都做相同的,那么这是一个单独的任务,应该由另一个班级完成。

所以我想说,首先重构LabTest它的组成部分(希望你有单元测试!)。然后当你开始写作时RadiologyTestEKGTest他们可以重用对他们有意义的部分。这也称为组合而不是继承。

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

于 2014-05-01T20:24:00.573 回答
1

我可能会因为这个答案而被烧毁,但无论如何都会四肢走动。在我看来(IMO),OCP 不能像 SRP、DIP 或 ISP 等其他原则那样在纯粹意义上被遵循。

如果需求以这样一种方式发生变化,您必须改变一个类的职责以使其对域模型的表示真实,那么我们必须改变那个类。

IMO,OCP 阻止我们重构代码以跟随系统的演变。

如果我错了,请纠正我。

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

于 2014-05-02T16:36:21.710 回答