Bad and Good Singleton's
About the design pattern of the Singleton gang of four has already been said a lot of nasty things. You can read about various principles violated by Singleton, for example, here . And it seems that I have something to add.
The root cause of all the troubles with GoF Singleton is that for the vast majority of classes, "Singleton" is a detail of their implementation. It’s just that it’s more convenient to implement these classes if the whole system will work with one single object of each. GoF advises that this implementation detail for all Singletones be brought out, in the form of the getInstance () method.
But what if it becomes necessary to implement the class differently? The problems will begin. If the new implementation is no longer Singleton, then you will have to change not only the class itself but also all its clients, removing all calls to getInstance () and thinking over the strategy of creating instances for each case again.
Is there any way to hide this property of the “Singleton” news of the class from its clients, along with all the problems and violated principles? Exist. This can be done using the Dependency Injection / Inversion of Control (IoC) architectural pattern. The IoC container (IoCC) hides the Singleton class from its clients and takes away all the responsibility for managing dependencies, freeing Singleton from: "... and provides it with a global access point ..."from the definition of a gang of four. The global access point is no longer needed, Singleton clients no longer know exactly how many instances of the dependency class IoCC creates for them. For example, my favorite IoCC Google Guice allows you to mark a class with Singleton annotation , but most importantly: it allows you to remove this annotation at any time without having to change class clients. Under the control of IoCC, the “Singleton'ovost” always remains a detail of the implementation of the class marked as Singleton .
There are exceptions when the "Singleton'ovost" really should be a property of the class interface, and not a detail of its implementation. One such exception: Flyweight Singleton. For example, we are writing classes for the abstract syntax tree of the SQL language, and one of such classes would be SqlNull. It is desirable that this class has one single object, so that everyone knows about it, and compare this object with the rest only by reference. In this case, GoF Singleton suits us perfectly.
So. For service classes, i.e. for most cases, "Singleton'ovost" is an implementation detail and IoCC allows to hide it; for Flyweight Singleton, this is part of the interface, and you can set it out as suggested by GoF using getInstance ().
The root cause of all the troubles with GoF Singleton is that for the vast majority of classes, "Singleton" is a detail of their implementation. It’s just that it’s more convenient to implement these classes if the whole system will work with one single object of each. GoF advises that this implementation detail for all Singletones be brought out, in the form of the getInstance () method.
But what if it becomes necessary to implement the class differently? The problems will begin. If the new implementation is no longer Singleton, then you will have to change not only the class itself but also all its clients, removing all calls to getInstance () and thinking over the strategy of creating instances for each case again.
Is there any way to hide this property of the “Singleton” news of the class from its clients, along with all the problems and violated principles? Exist. This can be done using the Dependency Injection / Inversion of Control (IoC) architectural pattern. The IoC container (IoCC) hides the Singleton class from its clients and takes away all the responsibility for managing dependencies, freeing Singleton from: "... and provides it with a global access point ..."from the definition of a gang of four. The global access point is no longer needed, Singleton clients no longer know exactly how many instances of the dependency class IoCC creates for them. For example, my favorite IoCC Google Guice allows you to mark a class with Singleton annotation , but most importantly: it allows you to remove this annotation at any time without having to change class clients. Under the control of IoCC, the “Singleton'ovost” always remains a detail of the implementation of the class marked as Singleton .
There are exceptions when the "Singleton'ovost" really should be a property of the class interface, and not a detail of its implementation. One such exception: Flyweight Singleton. For example, we are writing classes for the abstract syntax tree of the SQL language, and one of such classes would be SqlNull. It is desirable that this class has one single object, so that everyone knows about it, and compare this object with the rest only by reference. In this case, GoF Singleton suits us perfectly.
So. For service classes, i.e. for most cases, "Singleton'ovost" is an implementation detail and IoCC allows to hide it; for Flyweight Singleton, this is part of the interface, and you can set it out as suggested by GoF using getInstance ().