43

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?

Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
  • Here you go: http://kill-0.com/duplo/2010/02/05/on-the-difference-between-abstract-factory-and-dependency-injectioninversion-of-control/ . Seems you're not the only one wondering what's different between Service Locator and Abstract Factory patterns :) – Juliet Apr 18 '11 at 03:14

5 Answers5

48

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.)
Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26
  • +1; Good point about the purpose being different. I assumed this would be obvious by the names of the patterns, so I focused on the mechanics and public interface rather than the intention for use. This distinction is quite important in terms of lifecycle of the objects returned by the two classes. – Merlyn Morgan-Graham Feb 23 '12 at 09:12
  • 1
    I think intent is a defining characteristic of a pattern. For example, decorator and proxy could be implemented in the same way, but they have different intentions. – Gyan aka Gary Buyn Feb 23 '12 at 09:47
  • Accepting your answer in favor of mine because the intent of the pattern is more important than how the interface supports that intent. – Merlyn Morgan-Graham Mar 30 '13 at 20:34
  • Please give code samples to support what you said. It would make it much easier to understand – Adi Jun 26 '18 at 20:11
13

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)
Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
  • I'm not positive on my answer because I don't have much experience with the Service Locator pattern. If someone wants to contribute a more informed answer, feel free. – Merlyn Morgan-Graham Apr 24 '11 at 22:42
  • I am much more comfortable now with these concepts now. My answer is correct, but it is half the story. The intent is more important. See this other answer to the question - http://stackoverflow.com/a/9403827/232593 (also: I recommend not using a DI container except for implementing a plugin architecture. Use manual constructor injection inside your app boundary, with factories where you need them. Build object tree in main, or owning "module". Use Service Locator to connect to a true unreliable "service", not a process/system your program will own and has full control over ensuring is there). – Merlyn Morgan-Graham Sep 26 '16 at 17:38
3

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.

jfuentes
  • 477
  • 5
  • 8
  • I agree that Seemann's notion of Abstract Factory does not fit the GoF definition; but why do you say the GoF definition violates ISP? The intention is for every client to use every factory method. – jaco0646 Aug 08 '16 at 22:53
2

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.

Community
  • 1
  • 1
John Smith
  • 1,091
  • 9
  • 17
0

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.

jaco0646
  • 15,303
  • 7
  • 59
  • 83