我正在合并一个 CVS 分支,较大的更改之一是用具有静态初始化块和所有静态方法的抽象类替换单例模式。

这是值得保留的东西吗,因为它需要合并很多冲突,我会在什么样的情况下考虑这种重构是值得的?

我们在 Weblogic 8.1 下运行这个应用程序(因此 JDK 1.4.2)


对不起托马斯,让我澄清一下..

HEAD 版本具有传统的单例模式(私有构造函数、getInstance() 等)

分支版本没有构造函数,是一个“公共抽象类”,并将对象上的所有方法修改为“静态”。曾经存在于私有构造函数中的代码被移至静态块中。

然后该类的所有用法都被更改,这会导致合并中的多个冲突。

在一些情况下进行了这种更改。

有帮助吗?

解决方案

从严格的运行时性能角度来看,差异确实可以忽略不计。两者之间的主要区别在于“静态”生命周期链接到类加载器,而对于单例来说,它是常规实例生命周期。通常最好远离 ClassLoader 业务,这样可以避免一些棘手的问题,特别是当您尝试重新加载 Web 应用程序时。

其他提示

如果需要存储任何状态,我会使用单例,否则使用静态类。实例化某些东西是没有意义的,即使是单个实例,除非它需要存储某些东西。

静态不利于可扩展性,因为静态方法和字段不能被子类扩展或覆盖。

这也不利于单元测试。在单元测试中,您无法阻止不同测试的副作用溢出,因为您无法控制类加载器。在一个单元测试中初始化的静态字段将在另一个单元测试中可见,或更糟糕的是,同时运行测试将产生不可预测的结果。

当谨慎使用时,单例通常是一个不错的模式。我更喜欢使用 DI 框架并让它为我管理我的实例(可能在不同的范围内,如 Guice 中)。

如果我原来的帖子是正确的理解,并且与之相关的 Sun 的讨论是准确的(我认为可能是),那么我认为您必须在清晰度和性能之间进行权衡。

问自己这些问题:

  1. Singleton 对象是否使我正在做的事情更加清晰?
  2. 我是否需要一个对象来完成此任务,还是它更适合静态方法?
  3. 我是否需要不使用单例就能获得的性能?

根据我的经验,唯一重要的是哪个在单元测试中更容易模拟。我总觉得 Singleton 更容易、更自然地进行模拟。如果您的组织允许您使用 JMockit,那没关系,因为您可以克服这些问题。

这个讨论有帮助吗?(我不知道链接到另一个编程论坛是否是禁忌,但我不想只引用整个讨论=))

太阳关于这个主题的讨论

结论似乎是,在大多数情况下,它并没有产生足够的影响,尽管从技术上讲,静态方法更有效。

编写一些代码来衡量性能。答案将取决于 JVM(Sun 的 JDK 的执行方式可能与 JRockit 不同)和应用程序使用的 VM 标志。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top