服务定位器模式与抽象工厂模式有什么不同?

时间:2011-04-18 02:43:49

标签: design-patterns service-locator abstract-factory

乍一看,服务定位器模式与我的抽象工厂模式看起来相同。它们似乎都具有相同的用途(您查询它们以接收抽象服务的实例),当我读到有关依赖注入时它们都被提及。

然而,I have seen the Service Locator pattern described as a poor idea,但已见过direct support for the Abstract Factory pattern in at least one major Dependency Injection framework

如果它们不相同,有什么区别?

4 个答案:

答案 0 :(得分:42)

在调查这些模式时,我偶然发现了同样的问题。我认为服务定位器和工厂之间可以找到主要区别(无论是否抽象):

服务定位器

  • '找到现有的依赖项(服务)。尽管可以在解析期间创建服务,但对于客户来说并不重要,因为:
  • 服务定位器的客户端不取得依赖项的所有权

工厂

  • 创建依赖项的新实例
  • 工厂的客户取得依赖的所有权

抽象工厂

  • 与常规工厂相同,但不同的部署可能使用抽象工厂的不同实现,允许在不同的部署中实例化不同的类型(您甚至可以在运行时更改抽象工厂的实现,但通常不会如何使用它。)

答案 1 :(得分:13)

据我所知,到目前为止,我认为不同之处在于:

服务定位器模式

  • 明确支持注册应创建/返回的具体对象
  • 通常有一个通用接口,允许用户请求任何抽象类型,而不是特定类型
  • 可能是具体的

抽象工厂模式

  • 可能不支持注册 - 这取决于支持或不支持的具体实现,并且可能不会在抽象接口上公开
  • 通常有特定抽象类型的多个get方法
  • 本身不具体(虽然当然会有具体的实施)

答案 2 :(得分:2)

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

但阅读后

出现了一些严重的矛盾:

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

虽然Rober C. Martin没有提及有关泛型类型的任何内容,而且,他的书中的工厂示例允许创建多个类型对象的实例,使用键字串作为Factory.Make中的参数来区分它们( )。

Gamma表示抽象工厂的意图是“提供一个界面来创建相关或依赖对象的族,而不指定它们的具体类”。值得一提的是,Gamma抽象工厂示例违反了Martin所述的接口隔离原则(ISP)。 ISP和SOLID通常是更现代的原则,或者为了简单而省略。

Gamma和Martin的作品先于Seemann's,所以我认为他应该遵循已经做出的定义。

虽然福勒提出服务定位器作为实现依赖性倒置的一种方式,但Seemann认为它是一种反模式。 Gamma或Martin都没有提到服务定位器。

然而,Seemann和Fowler一致认为,服务定位器需要一个配置步骤来注册一个混凝土类的实例,该实例是在请求该类对象时稍后返回的内容。 Martin或Gamma在抽象工厂的定义中没有提到这个配置步骤。抽象工厂模式假设每次请求该类对象时都要实例化一个新对象。

<强>结论

Service Locator和Abstract Factory之间的主要区别在于Abstract Factory假设一个新对象被实例化,并在每个请求时返回,并且Service Locator需要配置一个对象实例,并且每次都返回相同的实例。

答案 3 :(得分:1)

自: http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/

  

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

     

另一方面,服务定位器是具有通用方法的非通用接口。单个服务定位器的Create方法可以返回无数类型的实例。