The singleton mentioned here is Singleton Design Pattern
- Private constructor
- Global referal to the instace
Singleton is global variable
The singleton instance can be access in every where. Actually, singleton instance is a group of global variables and methods. If we use singleton instance incorrectly, it will bring the problems from global vairables.
Why global variable is evil?
The root of the problem is, the dependencies of modules on global variable is not clear. It makes the module difficult to understand and test.
For example,1
2
3
4
5
6function foo(){
global $bar;
// or
$bar = Singleton::get_instance()->bar;
return ($bar > 10);
}
If we run foo()
, it can return true
or false
. As foo()
depends on $bar implicitly, we have no idea why the behaviour changed, until we read the source code. This means foo()
fail to abstract the detail of implementation.
How Singleton solve the implicitly dependency?
Singleton instance is similar to global variable, but it can solve the implicitly dependency casued by gloabl variable. What we need is “Dependency Injection”. It means we do not depend on the method directly in the implementation, but we pass the dependency using parameters.
Let’s rewrite foo()
1
2
3
4
5
6function foo($singleton){
$bar = $singleton->bar;
return ($bar > 10);
}
// We call foo() like this
foo(Singleton::get_instance());
Everytime, we call foo()
, we know which module it depends on. We can test the function easily by changing the dependency to a mock instance.
In another aspect, read-only global variable do no harm. If the Singleton’s fields are constant, and methods have no side effect, feel free to use Singleton. But in these case, static class or namespace may be a better choice.
To sum up, advantage of Singleton pattern faciliate dependency injection.
Lifespan of object is not a strong reason to use singleton
If only one object is needed in the whole software does not mean we must use singleton. We can just create an object and store it in somewhere but not in the global scope. We shoud handle the lifespan of the object careful. We cannot escape the responsiblity on lifespan handling by abusing Singleton pattern.
We need to understand what problem does the design pattern want to solve before applying them. “We only need one object” is not a sounded reason to apply Singleton. Software requirement always change, we only need one object now, but we may need more in the future. Applying design pattern in a wrong way make the system unneccesorily complex, increase the difficulty on developmention and maintainance.
Reference
PS: In the article they use a built in function dispatch_once()
, it makes the refactoring from singleton to object difficult. But in other language, singleton to objects may be a smooth transition