使用枚举实现实用程序类和单例

Peter Lawrey撰写了大多数人在他的博客上遗忘的两个Enums of Enums 。

首先,我没有忘记 – 我甚至没有意识到:)

这些方法简洁明了 – 与更传统的实现相同方法的方法相比,除了简洁之外还有什么好处,比如使用带有private构造函数的final类来实用类?

此外,是否有任何问题(除了令人困惑的程序员不期待它)?

我真的不同意该post中第一次使用enum 。 如果您想要一个不可实现的实用程序类,只需给它一个私有构造函数。 就这么简单,在我看到的那种情况下, enum没有提供额外的好处。

在实用程序类中使用枚举用于单例是很好的,但我通常会尝试保持enum被用作内部实现细节的事实。 例如,参见Guava的Predicates类,它使用enum来强制执行某些Predicate的单个实例,例如alwaysTrue() 。 它不会向用户公开enum

至于其他好处:是的,还有其他好处,例如内置的可串行化,并且每个类加载器绝对强制执行enum常量的单个实例,即使在反序列化时也是如此。

对于我来说,使用enums进行真正的枚举似乎更直观。

除了对非枚举事物使用枚举的混淆问题之外,使用Enums for monletons与其他硬编码单例范围的方法具有相同的缺点,基本上它阻碍了测试并使inheritance或其他扩展变得困难。 让单个范围由像Spring这样的工厂控制是一个更好的主意。

我在这两种情况下的第一直觉是他们是讨厌的黑客。

然而,在单例的情况下,我认为你可以合理地论证,在枚举常量是第一类对象的语言中,单例和只有一个值的枚举在概念上没有区别。 我仍然不确定我是否真的会使用这种技术,特别是因为单例模式因其他原因而非常不受欢迎。

使用实用类的枚举更难以防御。 没有概念上的理由将一组效用方法表达为枚举(可以说它们没有理由将它们表达为一个类,但这是另一个辩论)。 似乎以这种方式实现实用程序方法的唯一理由是通过忽略已建立的约定来节省一点点类型。

我不喜欢这种方法。 枚举应该保持简单的枚举。 它们最多应包含转换逻辑。 将enum用作单例或接口看起来像是一个混淆代码。