Design Patterns Mastery

State Pattern: Managing complex object lifecycles

2 Views Updated 5/6/2026

The State Pattern

The State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class. It is the sophisticated alternative to a giant, unmaintainable switch statement that checks if (status == Status.Paid) everywhere.

1. Solving "Conditional Hell"

Imagine an Order class. The Cancel() method does something different if the order is 'Pending' vs 'Shipped' vs 'Delivered'. Instead of 20 if statements, we create PendingState and ShippedState classes.

public abstract class OrderState 
{
    public abstract void Cancel(Order context);
}

public class ShippedState : OrderState 
{
    // In this state, cancellation is ILLEGAL!
    public override void Cancel(Order context) => throw new Exception("Already shipped!");
}

2. Why use it?

It follows the **Single Responsibility Principle**. All logic related to the "Shipped" status is in one place. If you want to add a new "Returned" state, you just create one new class. You don't have to find and edit 50 different switch statements across your codebase.

4. Interview Mastery

Q: "How is the State pattern different from the Strategy pattern?"

Architect Answer: "The structure is nearly identical, but the **Intent** is different. In **Strategy**, the client chooses the algorithm and passes it in (e.g., 'Use Zip compression'). In **State**, the object itself manages its transitions automatically behind the scenes (e.g., 'I am now Shipped, so I will now use the Shipped logic'). Strategy is a one-time choice; State is a continuous evolution."

Design Patterns Mastery
1. Introduction to Design Patterns
Introduction to GoF Patterns: Why patterns matter? SOLID Principles: The foundation of all patterns DRY, KISS, and YAGNI (Architectural Philosophy)
2. Creational Patterns
Singleton Pattern: Thread-safety & Captive Dependencies Factory Method: Abstracting complex object creation Abstract Factory: Creating families of related objects Builder Pattern: Constructing complex fluents Prototype Pattern: Cloning high-cost objects
3. Structural Patterns
Adapter Pattern: Bridging incompatible interfaces Bridge Pattern: Decoupling abstraction from implementation Composite Pattern: Managing tree structures & hierarchies Decorator Pattern: Enhancing behavior without inheritance Facade Pattern: Simplifying complex library subsystems Flyweight Pattern: Drastically reducing memory footprint Proxy Pattern: Interception, Lazy-Loading, and Security
4. Behavioral Patterns
Chain of Responsibility: Middleware & Pipeline Architecture Command Pattern: Implementing Undo/Redo & Queueing Interpreter Pattern: Building domain-specific languages Iterator Pattern: Unified traversal of collections Mediator Pattern: Decoupling components with MediatR Memento Pattern: Capturing and restoring object state Observer Pattern: Pub/Sub & Event-driven architecture State Pattern: Managing complex object lifecycles Strategy Pattern: Swappable algorithms at runtime Template Method: Defining skeleton algorithms Visitor Pattern: Separating operations from data structures
5. Modern Enterprise & Cloud Patterns
Repository & Unit of Work (The EF Core Standard) CQRS Pattern (Command Query Responsibility Segregation) Circuit Breaker & Retry Patterns (Resilience with Polly) Dependency Injection Pattern (The Modern King)