State Pattern: Phone Modes — Silent, Vibrate, Normal
The State Pattern lets an object change how it acts when its state changes. Instead of lots of if-else statements, you have a set of state objects that control the behaviour.
This makes it easy to add new states or change how things work in each state, without messing up the rest of your code. It is very helpful in games, workflows, and user interfaces.
Real-Life Analogy: Phone Modes — Silent, Vibrate, Normal
Think of your phone. When it's in Silent mode, incoming calls don't make noise. In Vibrate mode, it buzzes. In Normal mode, it rings. The phone is the same, but its response depends on its current mode.
That's the essence of the State Pattern: an object behaves differently depending on its internal state, but its interface stays the same.

Benefits of State Pattern
This pattern helps eliminate complex switch-case or if-else chains by moving state-specific logic into separate classes. Each state class handles only one situation, making the system easier to understand and extend.
When the object's state changes, it simply switches to another class that knows what to do.
- Keeps logic for each state separate and clear
- Makes code easier to test and modify
- Supports adding new states without touching existing logic
What to Implement
To apply this pattern, you need:
A state interface, one class for each state, and a context class that holds the current state and delegates behaviour to it.
- State Interface: Declares what the object can do
- Concrete States: Implement behaviour for specific modes
- Context: Stores current state and forwards calls
How It Works in C#
// State Interface
public interface IPhoneMode
{
void HandleIncomingCall(Phone phone);
}
// Concrete States
public class SilentMode : IPhoneMode
{
public void HandleIncomingCall(Phone phone)
{
Console.WriteLine("Incoming call... (No sound)");
phone.SetState(new VibrateMode());
}
}
public class VibrateMode : IPhoneMode
{
public void HandleIncomingCall(Phone phone)
{
Console.WriteLine("Incoming call... (Vibrating)");
phone.SetState(new NormalMode());
}
}
public class NormalMode : IPhoneMode
{
public void HandleIncomingCall(Phone phone)
{
Console.WriteLine("Incoming call... (Ringing)");
phone.SetState(new SilentMode());
}
}
// Context
public class Phone
{
private IPhoneMode _mode;
public Phone(IPhoneMode initialMode)
{
_mode = initialMode;
}
public void SetState(IPhoneMode mode)
{
_mode = mode;
}
public void IncomingCall()
{
_mode.HandleIncomingCall(this);
}
}
Usage:
var phone = new Phone(new SilentMode());
phone.IncomingCall(); // No sound
phone.IncomingCall(); // Vibrating
phone.IncomingCall(); // Ringing
When Should You Use It?
Use the State Pattern when an object must behave differently depending on its internal condition, and those behaviours should be cleanly separated.
It's ideal when:
- Objects go through well-defined state changes
- Behaviour needs to be updated without cluttering code
- You want to avoid large conditional statements
When Not to Use It: Avoid it for objects with very few simple states that rarely change — the extra structure may not be worth it.
Where Is It Used in the Real World?
The State Pattern is used in systems where behaviour must change based on internal state. It is a core concept for UI controls, game objects, and workflow engines.
- UI widgets (button: normal, hovered, pressed, disabled)
- Games (character states: idle, running, jumping, etc.)
- Workflow engines (steps with distinct behaviour)
- Media players (play, pause, stop states)
Final Thoughts
The State Pattern allows objects to switch behaviour dynamically without changing their interface. Like a phone changing how it reacts to calls based on its mode, your objects can respond differently without messy conditionals.
It brings clarity and flexibility to state-dependent behaviour — making your code easier to extend and maintain.