The Service Locator Pattern (Bonus: Implementation of an EventBus).

Ifeanyi Ibekie
4 min readNov 17, 2020

The service locator pattern is a design pattern used in software development 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 (Wikipedia). In simple terms, the service locator holds all the separate services you need to run tasks in your application and whenever you need a service you ask the service locator and it makes it available.

The service locator is mostly a runtime linker and as such, it is not really popular in dynamically typed languages due to the fact that it is set up mostly on runtime, the absence of type becomes a problem as these languages wouldn’t know how to report anomalies in the service locator and editors wouldn’t even provide IntelliSense affecting readability. With its imperfections, it is still a beautiful style of programming that you should embrace because it is a proponent of the methodology that isolates side effects from pure code and if you are able to ensure your service locator configurations and readability solutions are bulletproof or using a Strongly-Typed Language (for
JavaScript users e.g TypeScript), go ahead it is worthwhile as for the most part, design patterns are for developers, and as such very opinionated.

IMPLEMENTATION

The implementation of a service locator is straightforward as it is a healthy combination of IIFE’s and Closures. Here's an example in javascript:

From the file above (line 1 and line 47) you can see that the Locator was initialized using an Immediately Invoked Function Expression (IIFE) and it uses the encapsulation benefit of Closures to hide the internal state of the service locator while exposing functions that make up the functionality of the Service Locator. Ideally, in order to use Service Locator, your services should be wrapped in classes so that these classes can be registered in the Service Locator and the method of delivery of this services can be manipulated by the Service Locator.

From the file above only two delivery modes were implemented setSingleton and setFactory. The setSingleton function ensures that if you give the Service Locator an instance of a Class it keeps returning that same instance of the class and does not return a new instance. This approach is good for say an API service. For an API service using a token that is stored and used across requests, you can utilize this method as your requests would require a token and if a new instance is returned the already set token is lost. However, if you need to always return a new instance on demand the setFactory method is the implementation for that. Line 50 to 78 are examples for you to see how it works. Now that we have covered the basic concept of Service Locators let us look at a practical use-case for it “The EventBus”.

The Event Bus

An Event Bus follows the publish/subscribe pattern. It allows listeners to subscribe to events and publishers to fire events. This enables objects to interact without requiring to explicitly define listeners and keeping track of them. The Event Bus pattern is especially helpful for decoupling Controllers or Components of applications.

For example, the default Model-View-Controller style is cool but the moment you require cross interaction it could be a bit messy.

Messy MVC

The integration of an event bus style makes it cleaner

MVC with Event Bus

The question is how is it similar to the Service Locator explained above?. Well, It is similar because like the Service Locator the Event Bus has to be run as a singleton so that it would handle all the events in the application in a central place. Also, when it comes to mode of operation there is a similarity, as for the Service Locator it is the registration of services and the provision of the services on-demand, tweak that a little and we can turn it to the registration of event handlers and the calling of event handlers which is basically the mode of operation of an Event Bus. Let me show you how.

From the event bus script above you can tell that there are similarities between the implementation and that of the service locator. The “on” function registers an event with its key and also has the extra functionality to handle multiple registered event handlers by simply turning to an array. The “emit” function basically runs the stored handlers. Let us look at a use case with one of the most places in my humble opinion the event bus is needed, REACT.

From the Code Sandbox above I used the event bus to communicate between components no matter the depth in the component tree (simulated using the Nester component) in React. When going through the example note the fact that the event bus listeners should be registered and destroyed as done in the Counter component and the firing of events should be done like that in the Button component. If you encounter any issues related to scopes you can use “.bind(this)” for the event handlers to define their scopes.

In Conclusion, the Service Locator Pattern is a good approach to structure your code and with implementations of it like in the Event Bus, it just may be a must-have for your application. Feel free to tweak my implementations to cater for more requirements and edge-cases. Happy Coding!.

--

--