首页 文章

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

提问于
浏览
1

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

这些类有很多共同之处,因此有一个基类是有意义的 .

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

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

4 回答

  • 1

    我想你可以从两个角度看待它: existing requirementsnew requirements .

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

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

  • 1

    这些类有很多共同之处,因此有一个基类是有意义的 .

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

    所以我会说,首先重构 LabTest 进入它's constituent parts (hope you'已经进行了单元测试!) . 然后当你来写 RadiologyTestEKGTest 时,他们可以重用对它们有意义的部分 . 这也称为继承的组合 .

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

  • 2

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

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

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

    如果我错了,请纠正我 .

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

  • 1

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

    在你自己的情况下,我不会违反OCP,因为你已经提到过你所有的类使用取决于 LabTest 的抽象而不是 RadiologyTest 的实现 .

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

    应该清楚的是,没有重要的计划可以100%关闭 . 例如,如果我们决定在任何Square之前绘制所有Circles,请考虑清单2中的DrawAllShapes函数会发生什么 . DrawAllShapes函数未针对此类更改关闭 . 一般来说,无论一个模块是多么“封闭”,总会有一些变化,它不会被关闭 . 由于关闭不能完成,它必须是战略性的 . 也就是说,设计师必须选择各种变化来关闭他的设计 .

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

相关问题