The most used and (in)famous design pattern in the world is causing us great harm.
Problems
Coupling
Testability
Accidental implementation problems.
Multi threading issues.
Static methods polluting.
Object creation contract violation.
Bijection mismatch.
Memory issues.
Premature Optimization.

Code Smell 20 - Premature Optimization
Maxi Contieri ・ Nov 8 '20
Solutions
Avoid it.
Use contextual unique objects.
Benchmark object creation.
Examples
Database Access
Globals
Loggers
Helpers
Sample Code
Wrong
<? | |
class God { | |
private static $instance = null; | |
private function __construct() { } | |
public static function getInstance() { | |
if (null === self::$instance) { | |
self::$instance = new self(); | |
} | |
return self::$instance; | |
} | |
} |
God is the archetypical singleton example.
<? | |
final class God extends Singleton { | |
} | |
$christianGod = new God(); |
<? | |
$christianGod = God::getInstance(); | |
// Why should us be aware of getInstance when creating an object ? |
Right
<? | |
interface Religion { | |
// Define common behavior for religions | |
} | |
final class God { | |
// Different religions have different beliefs | |
} | |
final class PolythiesticReligion implements Religion { | |
private $gods; | |
public function __construct(Collection $gods) { | |
$this->gods = $gods; | |
} | |
} | |
final class MonotheisticReligion implements Religion { | |
private $godInstance; | |
public function __construct(God $onlyGod) { | |
$this->godInstance = $onlyGod; | |
} | |
} | |
// According to Christianity and some other religions, | |
// there’s only one God. | |
// This does not hold for other religions. | |
$christianGod = new God(); | |
$christianReligion = new MonotheisticReligion($christianGod); | |
// Under this context God is unique. | |
// You cannot create or change a new one. | |
// This is a scoped global. | |
$jupiter = new God(); | |
$saturn = new God(); | |
$mythogicalReligion = new PolythiesticReligion([$jupiter, $saturn]); | |
// Gods are unique (or not) according to context | |
// You can create test religions with or without unicity | |
// This is less coupled | |
// since you break the direct reference to God class | |
// God class Single Responsibility is to create gods. | |
// Not to manage them |
Detection
This is a design pattern. We should avoid it by policy.
We can add linter rules for patterns like 'getInstance()' so new developers cannot infect code with this anti-pattern.
Tags
- Globals
Conclusion
This is an historical mistake already acknowledged by the community. Nevertheless, lazy developers bring it again and again. We need to reach a consensus on its drawbacks.
Relations

Code Smell 18 — Static Functions
Maxi Contieri ・ Nov 6 '20
More info
Credits
Photo by Maria Teneva on Unsplash
The Diagram is Not the Model. The model is not the diagram. It is an abstraction, a set of concepts and relationships between them.
Eric Evans
Top comments (2)
How is
GodFactory
supposed to be used if it always throws?Hi. I changed the example and removed factory usage since I think it was a bit confusing