我正在合并一个CVS分支,其中一个较大的更改是使用具有静态初始化块和所有静态方法的抽象类的Singleton模式发生的替换。
这是值得保留的东西,因为它需要合并很多冲突,我会考虑哪种情况才能使这种重构变得有价值?
我们在Weblogic 8.1下运行此应用程序(所以JDK 1.4.2)
HEAD版本具有传统的单例模式(私有构造函数,getInstance()等)
分支版本没有构造函数,是一个“公共抽象类”,并将对象上的所有方法都修改为“静态”。以前存在于私有构造函数中的代码将移动到静态块中。
然后更改类的所有用法,这会导致合并中出现多个冲突。
有一些情况发生了这种变化。
答案 0 :(得分:16)
如果需要存储任何状态,我会使用单例,否则使用静态类。除非需要存储某些内容,否则实例化某些内容(即使是单个实例)也没有意义。
答案 1 :(得分:15)
从严格的运行时性能角度来看,差异实际上可以忽略不计。两者之间的主要区别在于“静态”生命周期与类加载器相关联,而对于单例,它是常规实例生命周期。通常最好远离ClassLoader业务,避免一些棘手的问题,尤其是当您尝试重新加载Web应用程序时。
答案 2 :(得分:11)
静态不利于可扩展性,因为子类不能扩展或覆盖静态方法和字段。
单元测试也不好。在单元测试中,由于无法控制类加载器,因此无法防止不同测试的副作用溢出。在一个单元测试中初始化的静态字段将在另一个单元测试中可见,或者更糟糕的是,同时运行的测试将产生不可预测的结果。
单调使用时通常是一种好的模式。我更喜欢使用DI框架,让我为我管理我的实例(可能在不同的范围内,如在Guice中)。
答案 3 :(得分:3)
如果我的原始帖子是正确的理解,并且与之相关的Sun的讨论是准确的(我认为可能是这样),那么我认为你必须在清晰度和性能之间进行权衡。
问自己这些问题:
答案 4 :(得分:3)
根据我的经验,唯一重要的是哪一个更容易在单元测试中模拟。我总觉得Singleton更容易自然地模仿。如果您的组织允许您使用JMockit,那么无关紧要,因为您可以克服这些问题。
答案 5 :(得分:0)
这个讨论有帮助吗? (我不知道是否禁止链接到另一个编程论坛,但我不想仅仅引用整个讨论=))
Sun Discussion on this subject
判决似乎是在大多数情况下它没有产生足够的差异,尽管技术上静态方法更有效。
答案 6 :(得分:0)
编写一些代码来衡量性能。答案将取决于JVM(Sun的JDK可能与JRockit不同)和应用程序使用的VM标记。