如何更换此Singleton?

时间:2012-04-13 03:27:47

标签: design-patterns dependency-injection singleton

所以我最近被添加到一个新的项目中,Java代码有大约10-15个Singleton类,它们在任何地方都可以使用。这些类的目的是从服务器(当客户端应用程序启动时)获取数据并在整个程序中访问该数据,这样就不必在每次需要时都进行服务调用,这在我看来是有意义的。

然而,在阅读了很多关于Singletons可怕的帖子后,由于紧密耦合和不可测试,我将如何更换它们?我被告知有关依赖注入,但我真的想继续将相同的数据传递给应用程序中的几乎每个对象吗?任何建议都很有用。

4 个答案:

答案 0 :(得分:2)

在这种情况下我使用依赖注入(DI),但正如你所说,你不喜欢它。

我能想到的下一件事是FACADE模式,创建一个ApplicationFacade类并在需要的地方进行DI。 (或者,如果你真的不喜欢DI,那就让它静止)

答案 1 :(得分:0)

我认为这取决于每个Singleton。例如,可以将Singleton分解为几个静态函数吗?或者它可以分解为几个较小的类。也许它仅用于应用程序的一小部分;因此,一个较小的类重构用于该模块。我认为,最终,它取决于每个Singleton的使用。如果它使你的代码更简单,更可扩展,更清洁等,那么保持它;如果没有,重构。

编辑:要补充一下,重构的需要是什么?代码简单,干净,是否有效?如果是这样,那么只需要向应用程序添加功能。始终寻找添加代码/功能,而不是修改现有代码。最后你必须回答,它是否可以扩展?

答案 2 :(得分:0)

看看Guice。您可以将构造函数定义为仅使用直接依赖项(没有工厂的工厂向下传递深度依赖项),使用@inject注释每个可注入构造函数,然后创建“模块”类,这些类定义用于任何抽象类的实现或那些构造函数中使用的接口。

Guice将使用反射魔法根据模块类中的指令查找实现并实例化对象图。它甚至足够聪明,可以自动使用no-arg构造函数用于您未在模块中明确定义的依赖项,而无需明确告知它。

你可以让Guice与你的架构纠缠在一起,但是如果你想要避免的是一系列用于注入依赖关系的工厂,那么一点点Guice就相当不错了。

答案 3 :(得分:0)

您可以设计类的方式是明确依赖性因素。如果一个类使用单例:

class Client {
  public void Method() {
    SomeService.getInstance().doSomething();
  }
}

隐藏在内部的依赖。为了解决这个问题,(1)采取建设或(2)采用相关方法,如果有意义(显示选项2):

class Client {
  public void Method(SomeService service) {
    service.doSomething();
  }
}

这是第一步。稍后,您可以从单例中提取接口并使用它。这是一个缓慢的过程:重构,重新测试,迭代......