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

发布于 2024-11-02 03:33:27 字数 383 浏览 2 评论 0原文

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

不过,我发现服务定位器模式被描述为一个糟糕的主意,但已经看到对抽象工厂模式的直接支持至少一个主要的依赖注入框架

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

At first glance, the Service Locator pattern looks the same as the Abstract Factory pattern to me. They both seem to have the same use (you query them to receive instances of abstract services), and they both have been mentioned when I read about Dependency Injection.

However, I have seen the Service Locator pattern described as a poor idea, but have seen direct support for the Abstract Factory pattern in at least one major Dependency Injection framework.

If they aren't the same, what are the differences?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌化 2024-11-09 03:33:27

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

服务定位器

  • “定位”现有依赖项(服务)。尽管服务可能在解析期间创建,但它对客户端没有影响,因为:
  • 服务定位器的客户端不取得依赖项的所有权

工厂

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

抽象工厂

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

I have stumbled across the same question while investigating these patterns. I think the major differences can be found between a Service Locator and a Factory (whether it is abstract or not):

Service Locator

  • 'Locates' an existing dependency (the service). Although the service may be created during resolution, it is of no consequence to the Client because:
  • The Client of the Service Locator does NOT take ownership of the dependency.

Factory

  • Creates a new instance of a dependency.
  • The Client of the Factory takes ownership of the dependency.

Abstract Factory

  • Same as a regular Factory except that different deployments may use different implementations of the Abstract Factory allowing different types to be instantiated in those different deployments (you could even change the implementation of the Abstract Factory at runtime but that's not usually how it's used.)
草莓味的萝莉 2024-11-09 03:33:27

从我到目前为止所读到的内容来看,我认为区别在于:

服务定位器模式

  • 显式支持注册应创建/返回的具体对象
  • 通常具有通用接口,允许用户请求任何抽象类型,而不是具体类型
  • 本身可能是具体的

抽象工厂模式

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

From what I have read so far, I think the difference is:

The Service Locator pattern

  • Explicitly supports registration of which concrete objects should be created/returned
  • Usually has a generic interface, allowing the user to request any abstract type, rather than specific types
  • May itself be concrete

The Abstract Factory pattern

  • May not support registration - that is up to the specific implementation to support, or not support, and probably wouldn't be exposed on the abstract interface
  • Usually has multiple get methods for specific abstract types
  • Is not itself concrete (though will of course have concrete implementations)
邮友 2024-11-09 03:33:27

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

然而,在阅读了

提出了一些严重的矛盾:

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

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

Gamma 表示,抽象工厂的目的是“提供一个接口,用于创建一系列相关或依赖对象,而无需指定它们的具体类”。值得一提的是,Gamma Abstract Factory 示例违反了 Martin 提出的接口隔离原则 (ISP)。一般来说,ISP 和 SOLID 是更现代的原则,或者可能是为了简单起见而省略了。

伽玛和马丁的作品先于西曼的作品,所以我认为他应该遵循已经做出的定义。

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

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

结论

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

Actually there is a clear separation between this both pattern. It's common known that both pattern are used for avoid dependencies from concrete types.

However after read

Some severe contradictions arises:

Seemann said: "An Abstract Factory is a generic type, and the return type of the Create method is determined by the type of the factory itself. In other words, a constructed type can only return instances of a single type."

While Rober C. Martin didn't mention anything about generic types and furthermore, factory example in his book allow to create instance of more than one type of objects distinguish between them using a key string as parameter in the Factory.Make().

Gamma said that intent of Abstract Factory is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes". Is worth to mention that Gamma Abstract Factory example violate Interface Segregation Principle (ISP) stated by Martin. ISP and SOLID in general are more moderns principles or maybe for simplicity where omitted.

Gamma and Martin's works precede Seemann's, so I think he should follow definition already made.

While Fowler propose Service Locator as a way to implement Dependency Inversion, Seemann consider it as an anti-pattern. Neither Gamma or Martin mention Service Locator.

However, Seemann and Fowler agreed in that Service Locator needs a configuration step to register an instance of a concretes class, that instance is what will be later returned when an object of that kind be requested. This configuration step is not mentioned by Martin or Gamma in their definition of Abstract Factory. Abstract Factory pattern suppose a new object to be instantiated every time an object of that kind be requested.

Conclusion

The main difference between Service Locator and Abstract Factory is that Abstract Factory suppose a new object be instantiated an returned at each requested and Service Locator needs to be configured with an object instance and every time the same instance will be returned.

囚你心 2024-11-09 03:33:27

从:
http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/< /a>

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

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

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

An Abstract Factory is a generic type, and the return type of the Create method is determined by the type of the factory itself. In other words, a constructed type can only return instances of a single type.

A Service Locator, on the other hand, is a non-generic interface with a generic method. The Create method of a single Service Locator can return instances of an infinite number of types.

稀香 2024-11-09 03:33:27

Martin Fowler 描述了服务定位器模式的几种实现,其中大部分是具体类,通过静态方法配置和调用。我认为我们可以忽略这些变化,并专注于他使用依赖注入的最后一个示例,这是一种更现代的方法。我们可以将其与 GoF 书籍中的抽象工厂模式进行比较。

抽象工厂的显着特征是一组固定的相关产品。相反,服务定位器具有无限的不相关产品集。这使得服务定位器更像是一个黑匣子,并可能导致主要的批评。模式的:它隐藏了 API 的依赖关系。当服务定位器实现为动态注册表时,客户端可能会请求不存在的产品。这对于抽象工厂来说是不可能的。

考虑到在抽象工厂和服务定位器之间进行选择,前一种模式更可取。但这是错误的二分法,因为有更多的选择。这两种模式都依赖于依赖注入,但 DI 在没有它们的情况下工作得更好。

注入是一种实现控制反转的机制。 IoC 是依赖倒置的理想形式,因为它最大限度地减少了客户端的复杂性并提供了最高级别的抽象。服务定位器和抽象工厂是在没有控制反转的情况下实现依赖关系反转的两种机制。从 IoC 理想的角度来看,它们都是不可取的,而且都没有实现。

有关 IoC 与 DI 的详细信息,请参阅:控制反转与依赖注入
有关抽象工厂和服务定位器陷阱的更多信息,请参阅:依赖注入代码味道

Martin Fowler describes several implementations of the Service Locator Pattern, most of which are concrete classes, configured and invoked via static methods. I think we can dismiss these variations and focus on his final example using dependency injection, a more modern approach. We can compare this to the Abstract Factory Pattern from the GoF book.

The distinguishing feature of an Abstract Factory is a fixed set of related products. Conversely, a Service Locator has an unlimited set of unrelated products. This makes Service Locator more of a black box, and leads to perhaps the primary criticism of the pattern: it hides dependencies of an API. When a Service Locator is implemented as a dynamic registry, a client may request nonexistent products. This is not possible with an Abstract Factory.

Given the choice between Abstract Factory and Service Locator, the former pattern is preferable. But this is a false dichotomy, because more options are available. Both of these patterns rely on Dependency Injection, but DI works even better without them.

Injection is a mechanism for achieving Inversion of Control. IoC is the ideal form of Dependency Inversion, because it minimizes complexity in the client and provides the greatest level of abstraction. Service Locator and Abstract Factory are two mechanisms of achieving Dependency Inversion without Inversion of Control. They are both undesirable from the perspective that IoC is ideal and neither of them achieves it.

For more info on IoC vs DI, see: Inversion of Control vs Dependency Injection.
For more info on pitfalls of Abstract Factory and Service Locator, see: Dependency Injection Code Smell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文