Skip to content

Latest commit

 

History

History
86 lines (69 loc) · 3.44 KB

Service locator pattern.md

File metadata and controls

86 lines (69 loc) · 3.44 KB

Service locator pattern

The service locator pattern is a design pattern used to encapsulate the processes involved in obtaining a service with a strong abstraction layer. This pattern uses a central registry known as the "service locator", which on request returns the information necessary to perform a certain task. Proponents of the pattern say the approach simplifies component-based applications where all dependencies are cleanly listed at the beginning of the whole application design, consequently making traditional dependency injection a more complex way of connecting objects.

Example

First of all let's create two services which will perform some operations:

class Service1 {
  fun action() {
    println("Action from Service 1")
  }
}

class Service2 {
  fun action() {
    println("Action from Service 2")
  }
}

After that we will create ServiceLocator interface and it's implementation:

interface ServiceLocator {
  val service1: Service1
  val service2: Service2
}

class ServiceLocatorImpl: ServiceLocator {
  override val service1: Service1 by lazy { Service1() }
  override val service2: Service2 by lazy { Service2() }
}

Then, I assumed that we have a class that needs two services to perform some operation. It will receive these two services with the help of a Patter - Service Locator:

class ServiceComposition(serviceLocator: ServiceLocator) {

  private val service1 = serviceLocator.service1
  private val service2 = serviceLocator.service2

  fun serviceInteraction() {
    service1.action()
    service2.action()
  }
}

and finally, example of usage:

class ServiceLocatorExample() {

  fun example() {
    val serviceLocator: ServiceLocator = ServiceLocatorImpl()
    val serviceComposition = ServiceComposition(serviceLocator)

    serviceComposition.serviceInteraction()
  }
}

Output:

Action from Service 1
Action from Service 2

Conclusion

Advantages:

  • The "service locator" can act as a simple run-time linker. This allows code to be added at run-time without re-compiling the application, and in some cases without having to even restart it;
  • Applications can optimize themselves at run-time by selectively adding and removing items from the service locator;
  • Large sections of a library or application can be completely separated. The only link between them becomes the registry;
  • An application may use multiple structured service locators purposed for particular functionality/testing. Service locator does not mandate one single static class per process;
  • The solution may be simpler with service locator (vs. dependency injection) in applications with well-structured component/service design.

Disadvantages

  • The registry hides the class' dependencies, causing run-time errors instead of compile-time errors when dependencies are missing (similar to using dependency injection);
  • The registry makes code harder to test, since all tests need to interact with the same global service locator class to set the fake dependencies of a class under test.

Links

Service locator pattern

Further reading

Service Locator pattern in Android

Inversion of Control Containers and the Dependency Injection pattern

Why service locator is so unpopular