Learn the difference between Singleton and Monostate design patterns in C# through a simple real-world story. Discover when to use each, how they work, and see full code examples to help you write cleaner, more maintainable code.
When designing applications in C#, we sometimes need to ensure that a class behaves in a global or shared way — whether that means only one instance exists, or that all instances share the same state.
Two popular design patterns for this are the Singleton and the Monostate. They might seem similar at first, but they’re actually quite different under the hood. Let’s explore both using a story you’ll never forget.
🏢 The Singleton Story: "One Manager for the Entire Office"
Imagine you work in a big company. There’s only one office manager, and her name is Sarah.
Everyone in the company talks to Sarah when they need:
- Time off approvals
- Issue resolutions
- General help
It doesn’t matter if you’re on the first or tenth floor — there’s just one Sarah, and she’s the only one you deal with. Even if someone tries to "create a new manager," the system will always redirect to the same Sarah.
That’s how the Singleton Pattern works in C#.
✅ Singleton Characteristics
- Only one instance exists across the entire application.
- Controlled through a static property.
- Used when only one shared object is needed (like configuration, logging, etc.).
🧪 Singleton in C\
public class OfficeManager
{
private static readonly OfficeManager _instance = new OfficeManager();
private OfficeManager() { }
public static OfficeManager Instance => _instance;
public void ApproveLeave() => Console.WriteLine("Leave approved by Sarah.");
}
Usage:
OfficeManager.Instance.ApproveLeave();
🏠 The Monostate Story: "Many Receptionists, One Phone Line"
Now picture a different scenario: A company has many receptionists at different desks.
Here’s the catch: They all share the same internal phone line.
So even if you speak to Receptionist A or Receptionist B, your message will go through the same shared communication system. It’s like they all have different faces, but the same brain for phone handling.
That’s the Monostate Pattern.
✅ Monostate Characteristics
- You can create multiple instances, but they all share the same state.
- Achieved using static fields in the class.
- Looks like a normal class, but behaves like a Singleton.
🧪 Monostate in C\
public class Receptionist
{
private static string _sharedPhoneLine;
public string PhoneLine
{
get => _sharedPhoneLine;
set => _sharedPhoneLine = value;
}
}
Usage:
var receptionist1 = new Receptionist();
receptionist1.PhoneLine = "Extension 101";
var receptionist2 = new Receptionist();
Console.WriteLine(receptionist2.PhoneLine); // Output: Extension 101
Even though receptionist2
is a different instance, it sees the same phone line!
📊 Singleton vs. Monostate: Key Differences
Feature | Singleton | Monostate |
---|---|---|
Instance Count | Only one instance | Multiple instances |
State Sharing | Instance-level | Shared static state |
Flexibility | Rigid (can't inherit or test easily) | More flexible and test-friendly |
Appearance | Feels like a global service | Feels like a regular object |
Use Case | Configs, Logging, Caching | Shared state without limiting instances |
🎯 When to Use Each?
-
✅ Use Singleton when:
- You want a single, global object (like a logger or configuration manager).
- You need to enforce that only one instance can ever exist.
-
✅ Use Monostate when:
- You want multiple instances that share the same state.
- You care about testability, inheritance, or flexibility.
🧠 Final Thoughts
Both Singleton and Monostate aim to provide shared behavior — but they approach it differently.
If you like to control instance creation, Singleton is your choice.
If you prefer to keep the illusion of multiple objects, while maintaining shared state, Monostate fits the bill.
Top comments (0)