The singleton design pattern is a powerful concept. The controversy around this subject however leaves many new developers confused regarding their utility and nature. Similar to the storyboard vs no storyboard debate, singleton has its lovers and haters. Rather than focus on their pros and cons, this article simply aims at explaining what singletons are and why they are used.
To illustrate an example where singletons may be of service, I created a simple project that demonstrates its utility. We begin by setting up a simple server using node.js.
This server is a restful API that serves json data at the /products, /users, and /orders endpoints. Now that our server is up and running, let’s create an iOS app with view controllers that use data from these routes. These view controllers are named after their respective endpoint.
Each view controller presents different information and therefore fetches data from varying endpoints. When we take a look at how these view controllers perform their network request, we find the following:
When observed side by side, the network code from the two view controllers contain a lot of redundancy. Each view controller is performing very similar network calls. The only thing that varies is their endpoints and the type of data they return..
There are a few shortcomings with this approach. First, there is a lot of redundant code. Second, the common variables that the network request depends on can quickly become out of synch because they are being implemented on separate view controllers. Lastly, a view controller shouldn’t really be making network calls, its job is to manage views.
Let’s clean this up by creating a singleton to centralize the common variables and network object into one location.
The code above shows the creation of a service class (APIService) whose role it is to perform all of our network operations. Naming is extremely important in programming. The static property called shared is what captures our singleton object. Its name “shared” is not an accident. It indicates that this is a shared resource that will be used by across multiple objects. In our case, these objects will be the three view controllers.
The UserViewController is now much lighter than before. Instead of performing a ton of network operations in its body, it simply calls the APIService singleton to fetch the json data from the users endpoint it passed to it. Once the data is obtained, the UserViewController utilizes the data in the unique way it desires. Other view controllers can adopt a similar pattern such as ProductsViewController below.
Through the use of singleton, our viewcontrollers are now less bloated. There is less redundant code throughout the app and common variables are now in a central location, allowing for changes to remain synchronized. Since this singleton is shared by all three view controllers, it gives us a single point of control for all our network operations. And that is the essence of singletons, establish a single point of control over a shared resource.