links: [[Creational Design Pattern]] --- ### The Singleton pattern restricts the instantiation of class to one "single" instance This is useful when exactly one object is needed to coordinate actions throughout the system. Some consider Singleton to be an anti pattern as it is frequently used in scenarios where it is not beneficial, introduces unnecessary restrictions in situations where a sole instance of a class is not required ### Why it's considered as anti pattern? - Violates Single Responsibility principle - all classes can create instances - testing becomes difficult ### When to use? - How can a class control it's instantiation? - How can it be ensured that a class has only one instance? - How can the sole instance of a class be accessed easily? - How can the number of instances of a class be restricted? - How can a global variable be accessed? Singleton pattern achieves this by - Hide the constructor of class - Define the public static operation(getInstance()) to return the sole instance of the class ### Common Uses - Singletons are often preferred to global variables as they do not pollute global namespace and provides lazy initialization ## Implementation An implementation of a singleton pattern must - ensure that only one instance of a singleton class ever exists - provides global access to that instance Typically this is done by - declaring all constructors of the class to be private - provide a static method that returns a reference to that instance The instance is usually stored as a private static variable; the instance is created when the variable is initialized, at some point before the static method is first called ```java // java public final class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton(){} public static Singleton getInstance() { return INSTANCE; } } ``` ```python // python class Singleton: __instance = None def __new__(cls, *args): if cls.__instance is None: cls.__instance = object.__new__(cls, *args) return cls.__instance ``` ```dart // dart class Singleton { static Singleton _instance; static Singleton get instance => _instance ?? Singleton._(); Singleton._() => _instance = this; } ``` ```dart // dart with factory class Singleton { static Singleton _instance; Singleton._(); factory Singleton() { if(_instance == null) { _instance = Singleton._(); } } } ``` ```js // using const variable const _data = []; const UserStore = { add: item => _data.push(item), get: id => _data.find(d => d.id == id) } Object.freeze(UserStore) export default UserStore ``` ```js // class based class Singleton() { constructor() { // do initialization } someFunc() { // } } const instance = new Singleton() Object.freeze(instance) export default instance ``` ### Lazy Initialization ```java public final class Singleton { private static volatile Singleton instance = null; private Singleton() {} public static Singleton getInstance() { if(instance == null) { synchronized(Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return instance; } } ``` --- tags: #patterns , #creational