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

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

然而,我已经将Service Locator模式描述为一个糟糕的主意,但至少在一个主要的依赖注入框架中直接支持Abstract Factory模式。

如果他们不一样,有什么区别?


我在调查这些模式时偶然发现了同一个问题。 我认为服务定位器和工厂之间可能存在重大差异(无论是否抽象):

服务定位器

  • '找到'现有的依赖项(服务)。 虽然服务可能在解决过程中创建,但对客户来说并不重要,因为:
  • 服务定位器的客户端不承担依赖关系的所有权。
  • 创建一个新的依赖项实例。
  • 工厂的客户端取得了依赖关系的所有权。
  • 抽象工厂

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

  • 从我目前阅读的内容来看,我认为不同之处在于:

    服务定位器模式

  • 明确支持应该创建/返回哪些具体对象的注册
  • 通常具有通用接口,允许用户请求任何抽象类型,而不是特定的类型
  • 可能本身就是具体的
  • 抽象工厂模式

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

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

    然而在阅读之后

  • 敏捷软件开发,原则,模式和实践[书]由罗伯C.马丁
  • 控制容器的反转和依赖注入模式[文章] Martin Fowler在http://martinfowler.com/articles/injection.html
  • 模式识别:抽象工厂或服务定位器? Mark Seemann撰写的文章,地址为http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/
  • Erich Gamma et al。设计模式[书]
  • 一些严重的矛盾出现了:

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

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

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

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

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

    然而,Seemann和Fowler同意,服务定位器需要一个配置步骤来注册一个混凝土类的实例,该实例是当请求该类对象时以后返回的实例。 Martin或Gamma在他们对抽象工厂的定义中未提及此配置步骤。 抽象工厂模式假设每次请求该类对象时都会实例化一个新对象。

    结论

    服务定位器和抽象工厂的主要区别在于,抽象工厂假设每个请求都会返回一个新对象,并且服务定位器需要使用对象实例进行配置,并且每次都会返回相同的实例。

    链接地址: http://www.djcxy.com/p/77753.html

    上一篇: Is the Service Locator pattern any different from the Abstract Factory pattern?

    下一篇: Dependency Injection vs Service Location