所以我最近被添加到一个新的项目中,Java代码有大约10-15个Singleton类,它们在任何地方都可以使用。这些类的目的是从服务器(当客户端应用程序启动时)获取数据并在整个程序中访问该数据,这样就不必在每次需要时都进行服务调用,这在我看来是有意义的。
然而,在阅读了很多关于Singletons可怕的帖子后,由于紧密耦合和不可测试,我将如何更换它们?我被告知有关依赖注入,但我真的想继续将相同的数据传递给应用程序中的几乎每个对象吗?任何建议都很有用。
答案 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();
}
}
这是第一步。稍后,您可以从单例中提取接口并使用它。这是一个缓慢的过程:重构,重新测试,迭代......