Design patterns by Tutorials — The power of OOP (part 2)
Singleton Pattern: pure-singleton and semi-singleton design pattern in Swift
Updated on 4th April 2019, 12:21 AM GMT 5:30+
Prerequisites — This blog series requires an intermediate level of expertise in object-oriented programming. You should have basic knowledge about class, object, constructor, inheritance, value and reference type. An Intermediates will gain knowledge and experts will sharpen his or her knowledge by reading this series from start to finish.
In object-oriented programming, a singleton class is a class that can have only one object during the whole life-cycle of an application or project.
Singleton design pattern is a part of iOS Applications life-cycle code. For example, in an iOS project, the UIApplication class is the best example of a singleton class, which is created by the iOS system on app launch and passed to the AppDelegate as a parameter in
There are two types of Singleton design patterns.
- Pure-singleton design pattern
- Semi-singleton design pattern
Pure-Singleton Design Pattern:
- In this pattern, a programmer who is using the functionality of a pure-singleton class is not allowed to create an instance of the class. A programmer can only call methods and access properties available for the singleton class by using the predefined instance of that class.
- The object of a pure-singleton class is automatically created during application launch with pre-defined parameters mentioned by the developer who created that class.
- Pure-singleton classes must be marked as final to avoid inheritance confusion. In swift, you can use structure also to achieve the same concept.
- A programmer cannot inherit the pure-singleton class. When you try to inherit any class in swift, you must call the constructor of the superclass. Calling the constructor of the superclass is not possible in pure-singleton class because all constructors of the pure-singleton class are always marked as private.
Let understand this design pattern in a simple way with below example.
- In the above example, PureSingletonDesignPatterExample1.swift we have marked all init methods as private of LogManger class so no one can create an instance of that class. If we try to create a sub-class of LogManger, the compiler will give you an error.
UIApplication, AppDelegate are examples of the pure-singleton class. Have you ever tried to create an object of UIApplication class manually? Try to do so and run the app. [What happened? App crashed, right? -I have tested this crash on swift 5, XCode 10.2]
Limitations of Pure-Singleton Design Pattern,
We cannot test the pure-singleton class with the test data. In the above example PureSingletonDesignPatterExample1.swift, suppose you want to test the LogManager class by pointing it to some test mode URL instead of production mode URL, we can not do that when we are writing test cases in XCTest target.
We can overcome this limitation by converting our pure-singleton class to semi-singleton class or by using the dependency injection pattern. I will write a dedicated article on dependency injection pattern. For now, let’s continue with the semi-singleton design pattern.
Semi-singleton design pattern:
- In semi-singleton design pattern, a programmer who is using the class is allowed to create an object of the singleton class if required. as well as also allowed to call methods and use properties of the singleton class.
- A programmer can also inherit the semi-singleton class if the singleton is not marked as final by the developer of the singleton class. In semi-singleton design pattern to mark the class as a final is not necessary.
- In the above example, SemiSingletonDesignPatterExample1.swift, we have not marked the init method as private, so we can create multiple instances of the semi-singleton class to remove the dependency from the property databaseURLEndpoint. Now we can create an object of the LogManger class by using any databaseURLEndpoint value, now our class LogManger follows the semi-singleton pattern.
UserDefault, FileManager, NotificationCenter are the example of semi-singleton classes. We can use pre-defined shared objects of UserDefault, FileManager, and NotificationCenter which are UserDefault.standard, FileManager.default and NotificationCenter.default.
The pre-defined object of pure or semi-singleton classes always lives in memory and never destroyed until you close the application. A programmer-defined object of semi singleton class destroyed after the scope of the object is completed.
Question: Which is a better way, “Pure-singletone design pattern” or “Semi-singleton design pattern”, when I should use the first one and when other one?
This totally depends on the responsibilities of your class. If you have created singleton class in your project and needs to change some of the properties at some point or if you want to add more responsibilities to the class by adding new methods in future and if you required its test cases also with mock data for newly added methods, you should go with the semi-singleton design pattern.
If you created your class, you are done with unit testing and want to publish it via a framework or library, you can go with pure-singleton design patterns. Because you created the class and some other developer will use it, so unit testing of your singleton-class is your responsibility before release, not the responsibility of the developer who is using it.
Thanks for reading this article.
You can give up to 50 claps: by long pressing the clap button.
if you enjoyed this article or learn something new, support me by sharing this article. Follow my profile so you don’t miss any future article.
Where to go from here?
Read other parts of this series ‘Design patterns by Tutorials — The power of OOP’
Part-1: Faceted and Fluent Builder pattern in Swift
Part-2: Singleton Design Pattern in Swift
Read my latest series ‘Protocol — The power of Swift’
Read my recent article UndoManager in Swift 5 with example
More parts coming soon…
Liked this article?
Give claps and show your support, Follow my profile
Stay tuned, @hitendrahckr is typing