Clean Code Basics: Singleton
Welcome again, brave coder 👨💻. We’re always still in the clean code basics series, where we tackle clean coding concepts like heroes! Today’s challenge is the Singleton Design Pattern. By the end of this article, I promise you that you will be a master of the Singleton DP (Design Patter) and gain 10X your Clean Code Concepts. Ready? Let’s go, Ala Barakati Lah!
What is the Singleton?
Imagine we’re playing a video game, let’s take a battle royal game for example like “Apex Legends” or “Call of Duty”. We have one and only one ☝️ legendary weapon in the whole game, and everyone who needs it has to share it. That’s the Singleton pattern.
In coding terms:
A Singleton ensures there’s only one instance of a class.
All parts of your app use the same instance.
It’s great for stuff like:
A global game leaderboard.
A shared database connection.
Why Use a Singleton?
You might be asking, why using the Singleton Pattern, while we can create a new fresh instance of a class whenever we need to do so! In some cases you’re right, we’ll need new fresh data instances, but for other cases Singleton can play a huge role like:
Avoid duplicating resources (like opening multiple database connections).
Make sure your whole app stays consistent with shared data.
Singleton Basic Example
I will be using JavaScript as I always used to do so, in my articles for simplicity reasons (but if you’re a fan of another language, just let me know).
❌The WRONG Way
I will be fixing this example later, but let’s just understand first, where the bad code implementation occurs!
class GameSettings {
constructor() {
this.settings = { difficulty: 'easy', volume: 10 };
}
}
const settings1 = new GameSettings();
const settings2 = new GameSettings();
settings1.settings.difficulty = 'hard';
// excpecting 'hard' to be printed
console.log(settings2.settings.difficulty);
// ❌😱 Output: 'easy'
Here, settings1 and settings2 are two separate instances.
Changing one doesn’t affect the other.
Inconsistent game settings!
The game settings is something that should be global to all app areas! That why we’ll need the Singleton Design Pattern here 😀
✅The RIGHT Way
Let’s implement the Singleton Patter properly.
class GameSettings {
constructor() {
// testing if the instance exists already
if (GameSettings.instance) {
return GameSettings.instance; // Return existing instance
}
this.settings = { difficulty: 'easy', volume: 10 };
// Store the current instance (this)
GameSettings.instance = this;
}
// update settings using a function
// to prevent touching the instance directly
updateSetting(key, value) {
this.settings[key] = value;
}
}
// Now we use the Singleton
const settings1 = new GameSettings();
const settings2 = new GameSettings();
settings1.updateSetting('difficulty', 'hard');
console.log(settings2.settings.difficulty); // 🎉 Output: 'hard' (consistent!)
console.log(settings1 === settings2); // 🎯 Output: true
What Just Happened?
We stored the instance in
GameSettings.instance
.If a second
GameSettings
object is created, it reuses the first one.Both
settings1
andsettings2
are the same object🎉
Use Cases to Call the Singleton Pattern
Global Configurations
Need app-wide settings, like theme or language? Use a Singleton.
const config = new ConfigManager();
Logging Systems
Want all parts of your app to write logs to the same file? Singleton.Networking
Limit database connections to one instance for efficiency? Singleton again!
PS: Singleton usage is not limited to only these 3 use cases, whenever you have a use case when you need to have the same shared instance in your app, use the Singleton Pattern!
When NOT to Use It!
The Singleton Pattern isn’t always the hero in all scenarios. Overuse, can turn your code into a mess!
Common Singleton Mistakes:
Hidden Dependencies
Your code relies on global state without realizing it, making bugs harder to slay.Testing Nightmares
Testing is harder when everything shares the same instance. Mocking becomes your new boss battle LOL.
🎉 Conclusion: Key Takeaways
The Singleton ensures a single shared instance of a class.
It’s handy for managing global resources, but don’t overuse it!
Boom! Now you're ready to crush the Singleton Pattern boss like a pro! See you in the next article, where we’ll be conquering new levels of Clean Code Patterns! Thelaaw 👋
🔔 Don't forget to subscribe to my blog and YouTube channel to stay updated with all the latest content!