服务定位器和工厂设计模式有什么区别?

15

我正在使用Unity并创建一个包装它的类,但我不知道该如何称呼它,服务定位器还是工厂?两者都封装了对象的创建,那么......有什么区别?

我正在使用Unity,并创建一个包装它的类,但我不知道应该如何称呼它,是服务定位器还是工厂?这两者都可以封装对象的创建,那它们有什么区别呢?

这个回答解决了你的问题吗?服务定位器模式与抽象工厂模式有什么不同? - Michael Freidgeim
3个回答

34

工厂会在请求时为您创建对象。

服务定位器返回可能已经存在的对象,也就是可能已经在某个地方为您存在的服务。

想一想这些名字的含义:

  • 工厂:是创建对象的地方。
  • 服务:是可以作为服务为您做某些事情的东西。
  • 服务定位器:是一种可以找到可以执行服务的东西。

最后的服务是一个类,它会执行某些操作。要检索它,必须创建它......服务定位器就像一个工厂,因为它必须制造一个“新”的实例。 - Fritjof Berggren
3
不需要创建新的服务对象,而是在尝试查找服务之前注册服务对象,可能是当应用程序启动时,以便将来服务定位器可以将该服务返回给调用者。 - Miguel Angelo
喜欢答案的“简洁”。 - Spock
唯一缺失的是接口名称 IServiceLocator 代表定位,IServiceFactory 代表创建,但可以有 ServiceLocator: IServiceFactoryIServiceFactory 有一个方法 GetService(name)。实现可以查找注入的服务,也可以创建新服务,因此是 Locator vs Factory,但如何命名接口才能保持中立?IServiceProvider - Pawel Cioch

12

实际上,这两种模式之间存在明显的区别。众所周知,这两种模式都用于避免依赖具体类型。

然而,在阅读以下内容之后:

出现了一些严重的矛盾:

Seemann说:“抽象工厂是一种泛型类型,Create方法的返回类型由工厂本身的类型确定。换句话说,构造的类型只能返回单个类型的实例。”

而Rober C. Martin没有提到任何关于泛型类型的内容,他书中的工厂示例允许创建多种对象类型的实例,并使用字符串作为参数在Factory.Make()中进行区分。

Gamma说,抽象工厂的目的是“提供一个创建相关或依赖对象族的接口,而不需要指定它们的具体类”。值得一提的是,Gamma的抽象工厂示例违反了Martin所述的接口隔离原则(ISP)。ISP和SOLID通常被视为更现代的原则,可能为了简化而被省略了。

Gamma和Martin的作品先于Seemann的作品,因此我认为他应该遵循已经确定的定义。

虽然Fowler提出服务定位器作为实现依赖反转的一种方式,但Seemann认为这是一种反模式。Gamma和Martin都没有提到服务定位器。

然而,Seemann和Fowler同意Service Locator需要一个配置步骤来注册具体类的实例,该实例在请求该类对象时将返回。Martin或Gamma在其抽象工厂定义中未提到此配置步骤。抽象工厂模式假定每次请求该类型的对象时都要实例化一个新对象。

结论

Service Locator和Abstract Factory之间的主要区别在于,抽象工厂假定每次请求时都会实例化并返回新对象,而Service Locator需要使用对象实例进行配置,并且每次都返回相同的实例。



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