代码之家  ›  专栏  ›  技术社区  ›  Tom Tresansky

单元素枚举类型singleton真的是一个被广泛采用的好主意吗?

  •  20
  • Tom Tresansky  · 技术社区  · 16 年前

    乔希·布洛克的第3项 通用程序设计 (使用私有构造函数或枚举器强制singleton属性)提到“虽然这种方法尚未广泛采用,但单个元素枚举类型是实现singleton的最佳方法。”

    例子:

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

    续:“这种方法在功能上等同于公共领域的方法,只是它更简洁,免费提供序列化机制,并提供了针对多个实例的铁壳保证,即使面对复杂的序列化或反射攻击。”

    我看到的最大的否定是:枚举不应该具有可变状态吗?在州里使用单件似乎很常见。

    那么,自出版之日(2008年第二版)以来,这种模式是否变得更加普遍?

    5 回复  |  直到 15 年前
        1
  •  10
  •   tlayton    15 年前

    虽然枚举通常不是给定的可变状态,但这一事实是基于如何使用枚举的假设。虽然这些假设通常是成立的,但它们并不总是成立的,在这种情况下,它们不成立于一个单例。

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

    至于这种设计模式的流行程度,我经常看到它,但并不是说它已经变得“普通”。

        2
  •  8
  •   Kevin Bourrillion Gergely    16 年前

    (此答案假定“强制”单件是 真的? 您想要什么,而不是由DI框架(如Guice)管理的事实上的单例 @Singleton ,这可能更经常是正确的想法。)

    把你的问题分解成两个:它真的被广泛采用了吗?不,不是应该的那么广泛。这是个好主意吗?对!

    JavaEnUM是一个类,它只能具有固定的N个实例集合,这些实例在源代码中被硬编码。

    singleton是一个类,它只能有一组固定的n个实例,这些实例在源代码中是硬编码的。n=1。

    就这么简单!

        3
  •  3
  •   user268396    16 年前

    枚举可以具有可变状态。通常这不是一个好主意,因为枚举的本质是拥有X大于1的Y类型的X版本,因此在状态(而不是使用字段/属性)之间进行切换就有点像噩梦,因为每个方法都需要考虑所有X枚举常量的所有可能状态。

    但是,如果您要定义一个枚举,无论如何只使用一个常量;您可以简单地将该单个常量视为一个普通的对象,并对其进行所有假设。IOW:拥有x版本的状态的问题消失了,因为x现在是1。

        4
  •  1
  •   Tom Hawtin - tackline    16 年前

    不 enum s不应该具有可变状态。静态值通常不应该是可变的。单粒子只是混淆可变静态的方法。(实现接口的无状态对象是另一回事。)

        5
  •  -4
  •   irreputable    16 年前

    这不是个好主意。

    它强制类从具体类继承 Enum . 这会污染您的类型层次结构。

    类型 INSTANCE 必须准确 Elvis ;它不能是 埃尔维斯 .

    一般来说,您没有自由选择实例的实例化方式。

    从语法上讲,这真的是太多的输入了吗?

    public class Elvis {
        static public Elvis INSTANCE = new Elvis();
    
    推荐文章