为了解码代码,您可以使用服务定位器,但这与全局变量/状态不同吗?
我知道这些通常会运行接口,所以你传入一个接口并获得一个具体的类,但我的问题仍然存在。
例如:
class Something {
void DoSomething() {
IMyType myType = ServiceLocator.GetSerivceTypeOf(IMyType);
}
}
这里的类需要在其他地方创建的MyType,但不是通过链(通过构造函数等......)传递MyType,而是以这种方式获取它。
我在职业生涯早期作为开发人员问过这个问题 - 在此之前我不会遇到这种模式。安东尼已经在服务定位器上发表了我的观点(因此现在是选定的答案) - 实际上我认为它们像其他人一样反模式。所提供的链接是一个很好的起点 - 但是在所有这些时间之后,它有点回答我自己的问题,它们充当全球状态,应该避免。首选标准依赖注入;)
答案 0 :(得分:3)
通常备份服务定位器模式的名称服务确实使用了全局的名称空间。
然而,必须考虑“全局变量”被认为是坏的原因。其中许多都围绕着在程序中的任何位置修改全局变量的能力。但是,大多数命名服务都可以限制对绑定对象的修改。对象本身可能是不可变的。
服务定位器不仅仅是一个全局变量,它是一个专业化。而这种专业化倾向于缓解全局变量可能产生的许多问题。
答案 1 :(得分:2)
是的,它们是全局变量。复杂的,但他们仍然有相同的基本缺点。因此,最好使用依赖注入。
有关构造函数注入的替代方法的更详细讨论,另请参阅问题What’s the difference between the Dependency Injection and Service Locator patterns?
以及其他网页Singletons are Pathological Liars和Dependency Injection pattern
答案 2 :(得分:1)
在某些时候,你需要一个具体的实现来做一些工作。从某种意义上说,该服务是“全球性的”,它对您的应用程序是“可用的”。但是您不必将其作为代码中的全局变量。
您可以撤消参数。如果您需要访问应用程序中的服务,您将使用什么模式来访问它,而不将其绑定到具体实现。没有太多选择。
某些资源对您的应用程序本质上是“全局的”,采用操作系统,文件系统,窗口系统,......
讨论比解决问题更具哲学性。无论如何,希望它有所帮助。