单例模式 vs 服务定位器

8
使用服务定位器或单例模式的优缺点是什么?我已经了解到单例模式不好,但我想知道使用服务定位器是否通常是更好的做法。
2个回答

14

两种方法都不好,因为从类的契约中无法明确它的依赖关系。也就是说,

private void foo()
{
    var x = SomeSingleton.Instance.GetX();
    var y = ServiceLocator.GetService<IProvider>().GetY();
}

在某个深处引用了 SomeSingletonIProvider

然而,与纯单例方法相比,服务定位器通常更好,因为它们允许更简单的集中配置、生命周期管理等。它们还允许更好的可测试性(您始终可以模拟对 GetService<T> 的调用)、更低的耦合度、关注点分离等。


2
我认为这两种方式都是反模式,但我同意服务定位器略微更可取。最好的解决方案是实现适当的依赖注入。 - Mark Seemann
从我对DI的理解来看,难道不需要让所有直接访问单例的对象都引用原先的单例对象吗? - djcouchycouch
是的,如果您使用构造函数注入(通常称为“声明依赖项”) ,则需要将它们作为参数传递给构造函数。为了简化事情,您可以使用控制反转容器。看一下Google Guice。 - Igor Popov
单例模式很麻烦,因为它们不利于松耦合。我正在尝试弄清如何使用Unity容器层次结构和Prism。由于Prism使用ServiceLocator单例,因此始终会看到根容器。 - m-sharp

1

如果测试性是一个关注点,使用服务定位器比纯单例更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接