Single-Element Enum Type Singleton真的是一个广泛采用的好主意吗?

Tom*_*sky 20 java design-patterns

Josh Block的Effective Java(使用私有构造函数或枚举器强制执行Singleton属性)的第3项提到"虽然这种方法尚未被广泛采用,但单元素枚举类型是实现单例的最佳方式."

例:

   public enum Elvis {
       INSTANCE;
       private final String[] favoriteSongs =
           { "Hound Dog", "Heartbreak Hotel" };
       public void printFavorites() {
           System.out.println(Arrays.toString(favoriteSongs));
       }
   }
Run Code Online (Sandbox Code Playgroud)

接下来:"这种方法在功能上等同于公共领域方法,除了它更简洁,免费提供序列化机制,并提供防止多个实例化的铁定保证,即使面对复杂的序列化或反射攻击."

我看到的最大的负面影响是:不是枚举不应该具有可变状态吗?使用具有状态的Singleton似乎很常见.

因此,自出版日期(2008年第2版)以来,这种模式实际上变得更加普遍吗?

tla*_*ton 10

虽然枚举通常不具有可变状态,但这一事实是基于如何使用枚举的假设.虽然这些假设通常都有,但它们并不总是如此,并且一个这样的情况,即它们不是在创建单身人士.

虽然它不是枚举的最常见用法,但是具有可变状态的枚举是完全合法的,尽管您可能希望在代码中指出这一事实,因此任何其他可能正在查看它的程序员都不会感到困惑.

至于这种设计模式的流行,我经常看到它,但并不是说我已经说它已经变得"普遍"了.


Kev*_*ion 8

(这个答案假设一个"强制"的单身人士真的是你想要的,而不是你的DI框架管理的事实上的单身人士(例如Guice @Singleton),这可能更经常是正确的想法.)

将你的问题分解为两个:它真的被广泛采用了吗?不,没有它应该的那样广泛.这是个好主意吗?是!

Java枚举是一个只能有一组固定N个实例的类,它们在源代码中是硬编码的.

单例是一个只能有一组固定N个实例的类,它们在源代码中是硬编码的.并且N == 1.

就这么简单!