【问题标题】:Are service locators not just global variables/state?服务定位器不仅仅是全局变量/状态吗?
【发布时间】:2010-11-01 23:21:12
【问题描述】:

为了解耦代码,您可以使用服务定位器,但这与全局变量/状态不同吗?

我知道这些经常运行接口,所以你传入一个接口并返回一个具体的类,但我的问题仍然存在。

例如:

class Something {

    void DoSomething() {
        IMyType myType = ServiceLocator.GetSerivceTypeOf(IMyType);
    }
}

这里的类需要 MyType,它是在其他地方创建的,但不是通过链(通过构造函数等)向下传递 MyType,而是以这种方式获取的。

我在我作为开发人员的职业生涯早期就问过这个问题 - 在此之前我没有遇到过这种模式。 Anthony 已经在服务定位器上确定了我的观点(因此现在是选定的答案)——事实上,我将它们视为与其他人一样的反模式。提供的链接是一个很好的起点 - 但在这么长时间之后,为了在某种程度上回答我自己的问题,它们充当全局状态,应该避免。更喜欢标准的依赖注入 ;)

【问题讨论】:

  • 一两个例子可能会引起讨论。

标签: language-agnostic dependency-injection service-locator


【解决方案1】:

通常支持服务定位器模式的名称服务确实使用全局名称空间。

但是,必须考虑“全局变量”被认为不好的原因。其中许多都围绕在程序中的任何位置修改全局变量的能力。但是,大多数命名服务可以限制对绑定对象的修改。对象本身可能是不可变的。

服务定位器不仅仅是一个全局变量,它是一种特殊化。而且这种专业化往往会缓解许多可能由全局变量引起的问题。

【讨论】:

  • 服务定位器的主要问题是它隐藏了依赖关系(misko.hevery.com/2008/08/17/singletons-are-pathological-liars)。服务定位器对缓解这个问题没有任何作用。并且很难用模拟服务代替测试,除非你再次使其可变,在这种情况下修改问题又回来了。
  • 当然,但这不是这个问题要问的。这里的对比是全局变量和名称服务之间的,而不是名称服务与世界之间的对比。
【解决方案2】:

在某些时候你需要一个具体的实现来做一些工作。从某种意义上说,该服务是“全球性的”,它对您的应用程序“可用”。但是您不必在代码中将其设为全局变量。

你可以颠倒这个论点。如果您需要访问应用程序中的服务,您将使用什么模式来访问它,并且不将其绑定到具体的实现。替代品不多。

某些资源本质上对您的应用程序来说是“全局的”,例如操作系统、文件系统、窗口系统……

与解决问题的讨论相比,讨论更具哲学意义。无论如何,希望它有所帮助。

【讨论】:

    【解决方案3】:

    是的,它们是全局变量。复杂的,但它们仍然具有相同的基本缺点。因此,依赖注入更可取。

    关于构造函数注入的替代方法的更详细讨论,另见问题What’s the difference between the Dependency Injection and Service Locator patterns?

    和其他网页Singletons are Pathological LiarsDependency Injection pattern

    【讨论】:

    • 问题不在于服务定位器是否是“最佳”模式,或者它是否比依赖注入更好。问题是它是否与全局变量相同(不是,-1),如果不是,是否更好。
    • 如果“ServiceLocator”不是全局变量,那么它是什么?您能否提供更详细讨论的链接。考虑这种模式的人应该知道首选的替代方案,因此链接更详细地讨论了这一点。
    猜你喜欢
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 2011-09-13
    • 1970-01-01
    • 2020-08-24
    • 2019-10-17
    • 1970-01-01
    相关资源
    最近更新 更多