It's easy to confuse the Abstract Factory pattern with the Service Locator anti-pattern - particularly so when generics or contextual information is involved. However, it's really easy to distinguish between there two, and here's how!

Here are both (anti-)patterns in condensed form opposite each other:

Abstract Factory Service Locator
public interface IFactory<T>
{
    T Create(object context);
}
public interface IServiceLocator
{
    T Create<T>(object context);
}

For these examples I chose to demonstrate both as generic interfaces that take some kind of contextual information (context) as input.

In this example the context can be any object, but we could also have considered a more strongly typed context parameter. Other variations include more than one method parameter, or, in the degenerate case, no parameters at all.

Both interfaces have a simple Create method that returns the generic type T, so it's easy to confuse the two. However, even for generic types, it's easy to tell one from the other:

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.

Even simpler:

An Abstract Factory is a generic type with a non-generic Create method; a Service Locator is a non-generic type with a generic Create method.

The name of the method, the number of parameters, and other circumstances may vary. The types may not be generic, or may be base classes instead of interfaces, but at the heart of it, the question is whether you can ask for an arbitrary type from the service, or only a single, static type.


Comments

mmm... i generally agree and it's an easy way to create a simple rule set for those learning the patterns. but i'm having a hard time with this one for a couple of reasons.

1) i've always viewed an IoC container (whether it's used for dependency injection or service location) as an amalgamation of design pattern, including the abstract factory (along with builders, registries, and others)

2) a design pattern is not always identified by implementation detail, but by intent. take a look at the Decorator and Proxy design patterns as implemented in C#, for example. There are, quite often and in the most basic of implementations, very few differences between these two patterns when it comes down to the implementation. the real difference is the intent of use

i don't think you are necessarily wrong in what you've said. i do think there's much more room for a gray area in between these two patterns, though. a service locator is an abstract factory (along with many other things), and an abstract factory can be used as a service locator. so, while the two patterns are distinct in their intent, they are often blurred and indistinguishable in implementation.
2010-11-01 13:08 UTC
Good point about design patterns not always being identifiable by implementation details. That's not quite what I said, either... We can distinguish between the two from differences in the structure of their public APIs. That's not the implementation, but rather the shape, of the type. Still, point taken.

However, the whole point is that there are fundamental differences between Abstract Factory and Service Locator. One is good, the other is evil. Learning to tell them apart is important.
2010-11-01 20:23 UTC
"An Abstract Factory is a generic type with a non-generic Create method"
is it? looks to me like the Create method IS generic, it just so happens to have a constraint
2010-11-14 04:08 UTC
True, but I'm sure you understand what is meant :)
2010-11-14 08:10 UTC


Wish to comment?

You can add a comment to this post by sending me a pull request. Alternatively, you can discuss this post on Twitter or Google Plus, or somewhere else with a permalink. Ping me with the link, and I may add it as a comment.

Published

Monday, 01 November 2010 12:31:53 UTC

Tags



"Our team wholeheartedly endorses Mark. His expert service provides tremendous value."
Hire me!