Removing Singletons

Problem: your code has a big badass manager class with a singleton interface, and you would like to have more flexible, testable code.

The code samples in this article are in Swift, but the concepts translate to pretty much any modern language.

class Manager {
    static let singleton = Manager()
}

Recipe

Create a protocol called ManagerProtocol (Objective-C, Swift) or an interface ManagerInterface (Kotlin, Java, C#), or an abstract class with pure virtual methods IManager (C++) to contain the signatures of the public properties of your manager.

protocol ManagerProtocol {}

Make the singleton return a ManagerProtocol, instead of a Manager.Make your class comply to the protocol; that is, implement the interface.

class Manager: ManagerProtocol {
    static let singleton: ManagerProtocol = Manager()
}

Now your code will most probably not compile; add the signatures of the public methods and properties that you client code requires to the protocol / interface until everything compiles again.

In the classes that use the singleton, create a public property of type ManagerProtocol and initialize it to the value of the singleton at initialization or construction time: in other words, turn this

class Client {
    func method() {
        Manager.singleton.doThat()
    }
}

into this

class Client {
    var manager: ManagerProtocol = Manager.singleton

    func method() {
        self.manager.doThat()
    }
}

Replace every instance of the singleton call with a call to the ivar.

Result

Now your components are decoupled; you can replace the Manager class at runtime with another object, and this is useful for testing your code. It can also be useful at runtime, to switch the behaviour of your code from one implementation to another if needed.

Another side effect is that you have a nice interface / protocol that describes your “manager” as an abstract entity, and this is a powerful tool for documenting the code and establishing relationships among things.