15

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

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

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


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

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

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

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

在少数情况下进行了此更改。

4

7 回答 7

16

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

于 2008-08-26T14:59:20.503 回答
15

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

于 2008-08-26T14:52:01.783 回答
11

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

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

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

于 2008-08-26T17:52:52.363 回答
3

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

问自己这些问题:

  1. Singleton 对象是否使我正在做的事情更清楚?
  2. 我需要一个对象来完成这项任务还是更适合静态方法?
  3. 我是否需要不使用 Singleton 可以获得的性能?
于 2008-08-26T14:54:56.380 回答
3

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

于 2008-08-26T15:14:26.630 回答
0

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

孙 讨论这个话题

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

于 2008-08-26T14:50:44.987 回答
0

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

于 2008-09-09T01:44:43.197 回答