共享单例实例

时间:2011-07-25 12:18:07

标签: java design-patterns singleton

我正在实现一个程序,该程序使用具有单例行为的共享实用程序类。

实用程序类的一个实例在主线程中创建,并传递给实例化的所有其他对象:

SomeUtil util = new SomeUtil();

...

Foo foo = new Foo(util, arg1, arg2)
Bar bar = new Bar(util, arg3, arg4, arg5) 

是否有一些更优雅的方法(即设计模式)?

5 个答案:

答案 0 :(得分:4)

为什么要绕过实用程序对象? SomeUtil可以有静态方法,因此Foo和bar中的方法可以使用它。

此外,您可以实现实际的单例模式。

答案 1 :(得分:4)

正如其他人所说,Singleton可以替代。请注意,您当前的设计很容易进行单元测试(因为您注入了SomeUtil依赖项,因此在单元测试期间可以很容易地被模拟对象替换),而Singleton使单元测试变得笨拙和困难:

  • 它使您的对象依赖于全局状态,因此更难以正确设置测试,并且容易出错(例如,忘记为特定测试正确初始化Singleton),
  • 理解代码更加困难,因为除了实际读取整个代码之外,您无法轻易识别给定的代码片段是否依赖于全局状态。

话虽如此,如果它是一个真正的实用类,即它没有内部状态,并且它不依赖于任何会使单元测试变得困难的东西(如数据库或文件系统),它可以将它用作Singleton(虽然这引出了一个问题,为什么你需要实例化它 - 通常实用程序类只有静态方法,而私有构造函数可以防止实例化。)

答案 2 :(得分:3)

好吧,你实际上可以使用singleton pattern,它通常会在类本身中存储一个静态引用。

public class SomeUtil {
    private static final SomeUtil instance = new SomeUtil();
    public static SomeUtil getInstance() { 
        return instance;
    }
    //...
}

这样做可以减少单元测试,但请注意。打破注入的依赖关系通常比全局依赖关系容易得多。

答案 3 :(得分:1)

为什么不只是一个真正的单身人士?比在任何地方传递一个实例要好得多。

答案 4 :(得分:1)

解决这个问题的最好方法可能是添加/使用一些依赖注入框架。

  • 框架将保证对象确实是单例(传统上有点棘手,特别是在以懒惰方式完成时)
  • 您可以在测试
  • 时替换/控制单例'实例'
  • 你可以摆脱singleton-passing-as-constructor-parameter(如果你愿意)