Service Locator模式与Abstract Factory模式有什么不同?
乍看之下,服务定位器模式看起来与抽象工厂模式相同。 他们似乎有相同的用途(你查询他们接收抽象服务的实例),他们都已经提到,当我读到dependency injection。
但是, 我已经将Service Locator模式描述为一个糟糕的主意 ,但是至less在一个主要的Dependency Injection框架中直接支持Abstract Factory模式 。
如果他们不一样,有什么区别?
我在调查这些模式时偶然发现了同样的问题。 我认为服务定位器和工厂之间可能存在主要的差异(无论是否抽象):
服务定位器
- “定位”一个现有的依赖项(服务)。 尽pipe服务可能在解决过程中创build,但对客户来说并不重要,因为:
- 服务定位器的客户端不承担依赖关系的所有权 。
厂
- 创build一个依赖项的新实例 。
- 工厂的客户拥有相关的所有权 。
抽象工厂
- 除了不同的部署可能会使用抽象工厂的不同实现,允许在不同的部署中实例化不同的types(甚至可以在运行时更改抽象工厂的实现,但这通常不是如何使用的),它与常规Factory相同。
从我目前阅读的内容来看,我认为不同的是:
服务定位器模式
- 显式支持应该创build/返回哪个具体对象的注册
- 通常有一个通用的接口,允许用户请求任何抽象types,而不是特定的types
- 可能本身就是具体的
抽象工厂模式
- 可能不支持注册 – 这是由具体的实现来支持,还是不支持,并且可能不会暴露在抽象接口上
- 通常对于特定的抽象types有多个get方法
- 本身不具体(虽然当然会有具体的实现)
其实这两种模式之间有明显的分离。 众所周知,两种模式都用于避免具体types的依赖。
但是在阅读之后
- 敏捷软件开发,原理,模式和实践[书籍]由罗伯C.马丁
- 控制容器的倒置和dependency injection模式[文章] Martin Fowler在http://martinfowler.com/articles/injection.html
- 模式识别:抽象工厂或服务定位器? Mark Seemann撰写的文章http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/
- devise模式[书]由Erich Gamma等
一些严重的矛盾出现了:
Seemann说:“抽象工厂是一个genericstypes,Create方法的返回types是由工厂本身的types决定的,换句话说,构造types只能返回单一types的实例。
虽然罗伯特·C·马丁没有提到任何关于genericstypes,而且他的书中的工厂例子允许创build多个types的对象的实例使用一个键string作为Factory.Make()中的参数来区分它们。
Gamma表示,抽象工厂的意图是“提供创build相关或依赖对象的家族的界面,而不指定具体的类”。 值得一提的是,Gamma抽象工厂的例子违反了Martin所说的接口隔离原则(ISP)。 一般而言,ISP和SOLID是更现代化的原则,或者为了简单起见,省略。
伽马和马丁的作品先于西曼的作品,所以我觉得他应该遵循已经定义的定义。
虽然福勒提出服务定位器作为一种实现依赖倒置的方法,但是Seemann认为这是一种反模式。 Gamma或Martin都没有提到服务定位器。
然而,Seemann和Fowler同意,服务定位器需要一个configuration步骤来注册一个混凝土类的实例,这个实例是当这种types的对象被请求时将被返回的东西。 Martin或Gamma在Abstract Factory的定义中没有提到这个configuration步骤。 抽象工厂模式假设一个新对象被实例化,每当这种对象被请求。
结论
服务定位器和抽象工厂的主要区别在于,抽象工厂假设一个新的对象被实例化,每个请求都返回一个对象,服务定位器需要configuration一个对象实例,并且每次都返回相同的实例。
来自: http : //blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/
Abstract Factory是一个genericstypes,Create方法的返回types是由工厂本身的types决定的。 换句话说,构造types只能返回单一types的实例。
另一方面,服务定位器是一个通用方法的非generics接口。 单个Service Locator的Create方法可以返回无数个types的实例。