代码之家  ›  专栏  ›  技术社区  ›  akarnokd

枚举单件有处罚吗?

  •  2
  • akarnokd  · 技术社区  · 15 年前

    是否有(绩效)处罚*与 Enum Singleton Pattern 在任何方面,它似乎都比经典的单例模式或内部持有者类习语少用?

    *惩罚,比如在不需要的情况下可串行化的成本,或者是使用率低,因为开发者很少阅读有效的Java第二版?

    2 回复  |  直到 15 年前
        1
  •  5
  •   dfa    15 年前

    所有JavaSuntLon模式(这两个标准以及私有构造函数和静态访问器的标准)都有这样一个坏的属性,如果您要测试它们(或者测试甚至远程依赖它们的任何东西),可以使用这个,而只使用这个对象。

    例如,如果您想测试 PrintingService 取决于 PrintingSingleton 您将无法将此打印单例替换为模拟,因为它是静态绑定的。

    也就是说,想象一下测试这个函数

    boolean printDocument(Document d) {
      if (PrintingSingleton.INSTANCE.isPrinterEnabled()) {
        PrintingSingleton.INSTANCE.print(d);
      }
      throw new RuntimeExeption("Printing not enabled");
    }
    

    通过测试

    @Test(expectedExceptions = {RuntimeException.class})
    public void testPrinting() {
      PrintingService service = ...
      service.print(new Document());  // How will you simulate 
                                      // throwing an exception?
    } 
    

    就个人而言,我只是避免使用单例,而是通过guice、spring或pico容器引入依赖注入。这样,您可以确保只有一个对象的存在,而不限制您自己无法模拟出对象,例如用于测试。

        2
  •  1
  •   Adam Goode    15 年前

    对于使用基于枚举的单例,您不会受到任何性能惩罚,因为枚举实际上只是运行时的常规类。我想在类装入时您可能会受到非常轻微的性能影响,因为系统可能正在执行正确性所需的所有正确初始化。序列化应该没有成本,因为这只是一个标记接口,只有在您尝试序列化时才进行检查。它真的是最著名的方法创建单例!