Sup*_*hne 5 java oop enums open-closed-principle solid-principles
在java中,如果我们使用枚举并且最终我们想要从该枚举中添加/删除属性,因此它的用法,我们在实体原则中违反了开放/封闭原则.
如果是这样,枚举的更好用法是什么?
答案是否定的,因为OCP不适用于(并且不能适用)Enums.枚举应该是完整的(包含所有可能的值)和静态的(静态=最终的,不可变的).您可以将它们视为一组有限的值对象.
如果你想要一些可以扩展的东西,你总是可以使用一个类或构建你自己的"类型安全枚举",可以扩展.
关于语言.我选择使用术语" 应用"而不是" 违反 "作为原则,因为许多良好实践都具有适用它们的上下文.违规(对我来说)意味着情况要求使用原则,但它没有被使用或者没有正确实施.它不适用意味着它在锡上所说的,原则在当前环境中没有用,或者它不能被应用,否则将违背其他具有更强大力量的原则......在上下文中:).
我认为Enums不违反OCP的另一个原因(现在我使用了violate:D 这个词),是因为OCP并不意味着所有的类和方法都可以扩展,而是一个尽职尽责的开发人员做出明智的决定放置这些扩展点的位置.在Enum开发人员理解的情况下,不需要扩展可能的值,并且进一步增加新值会有害,因为现有代码不知道如何处理新值.所以他/她决定完全关闭课程而不提供扩展点.这同样适用于任何其他类final.一final类不违反OCP,而是(或理想)开发者做出不允许延长它的决定.
这类似于我之前提到的,Enums就像一组有限的小值对象.VO是不可变的并且是封闭的,因此它们不违反OCP.
为了增加更多内容,我发现有些库没有正确实现OCP(Tapestry 5)并且需要进行超过最终的操作,这使得它们成为PITA使用的.或者只是没有关闭任何东西,这使得一些开发者犯错误,因为他们不了解库的更精细的细节,并搞砸了不变量.
答案是肯定的。所有 Java 枚举都违反了开闭原则,因为它们不能在不修改的情况下扩展。
Java 中“更好地使用枚举”是让它们实现一个接口,并让客户端依赖于该接口而不是枚举实现,因为该接口不违反开放/关闭原则。
不要急于得出这样的结论:如果枚举违反了 OCP,那么我们就不应该被允许使用它们。我想通过提醒来澄清这个答案,根据定义,OCP 仅适用于面向客户端的代码,即公开/公开的代码。OCP 不限制实施细节。
如果一个模块可供其他模块使用,则该模块被称为关闭...在实现级别,模块的关闭还意味着您可以编译它,也许将其存储在库中,并使其可供其他模块使用(其客户)使用。
——Bertrand Meyer,《面向对象的软件构建》第二版。第57页
因此,利用枚举作为应用程序内部 API 的一部分可以完全避免 OCP。它只是作为外部 API 的一部分,其中枚举应该通过接口进行抽象。
考虑一下,由于枚举是一个具体的实现,因此只有在接口与 OCP 一样满足依赖倒置原则时才公开它。即使您认为直接公开枚举在某种程度上回避了 OCP,它仍然会创建具体的依赖关系,从而违反了 DIP。
另请考虑@MarkRotteveel 的评论,“开放/封闭是一个原则,而不是需要始终遵循的教条。”