views:

145

answers:

3

In order to decouple code you can have service locater's but is this not the same as global variables/state?.

I know these often run off interfaces, so you pass in an interface and get a concrete class back but still my question stands.

For example:

class Something {

    void DoSomething() {
        IMyType myType = ServiceLocator.GetSerivceTypeOf(IMyType);
    }
}

Here the class requires MyType which is created somewhere else, but rather than passing MyType down through the chains (via constructors etc...) it is acquired in this manner.

I asked this question early in my professional career as a developer - prior to then I'd not come across this pattern. Anthony has nailed my opinion (and therefore is the selected answer now) on service locator's - in fact I see them as anti-patterns like others. The links provided are a good starting point - but to somewhat answer my own question after all this time, they act as global state and should be avoided. Prefer standard dependency injection ;)

+2  A: 

The name service that typically backs up the service locator pattern does indeed use a name space that is global.

However, one has to consider the reasons "global variables" are considered bad. Many of these revolve around the ability to modify a global variable anywhere in the program. However, most naming services can restrict modifications to a bound object. The object itself may be immutable.

Service locator is not simply a global variable, it is a specialization. And that specialization tends to mitigate many of the problems that can arise from global variables.

erickson
the main problem with service locator is that it hides dependencies ( http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/ ). Service locator does nothing to mitigate that problem. And it's hard to substitute a mock service for testing, unless you make it mutable again, in which case the modification problems are back.
Anthony
A: 

At some point you need a concrete implementation to do some work. The service is "global" in a sense that it is "available" to your application. But you do not have to make it a global variable in your code.

You can reverse the argument. If you need to access a service in your application, what pattern would you use to access it, and without binding it to a concrete implementation. There are not many alternatives.

Some resources are intrinsically "global" to your application, take the operating system, the file system, the windowing system, ...

The discussion is more philosophical one than a problem solving one. Anyway, hope it helps.

Bruno Ranschaert
A: 

Yes they are global variables. Sophisticated ones, but they still have the same basic drawbacks. For that reason, dependency injection is preferable.

For more detailed discussion of the alternative of constructor injection, see also the question What’s the difference between the Dependency Injection and Service Locator patterns?

And other web pages Singletons are Pathological Liars and Dependency Injection pattern

Anthony
The question isn't whether service locator is the "best" pattern, or whether it is better than dependency injection. The question is whether it's the same as global variables (which it is not, -1), and if not, whether it's better.
erickson
If "ServiceLocator" isn't a global var, then what is it? Can you provide links to a more detailed discussion.Someone considering this pattern should be aware of the preferred alternatives, hence the links which discuss this in more detail.
Anthony