"Most software bugs don't happen because developers create the wrong classes. They happen because the system allows an object to enter a state it should never have been allowed to reach."
Imagine you're building an e-commerce application.
A customer places an order.
The payment succeeds.
The warehouse ships the package.
Everything looks fine.
Now imagine the system accidentally allows the order to be cancelled after it has already been delivered.
Or suppose a refund is issued even though the payment failed.
Neither problem is caused by poor coding syntax.
They're caused by invalid state transitions.
Every important object in a software system goes through a lifecycle.
Understanding that lifecycle is one of the most valuable skills in Low-Level Design.
That's exactly what State Diagrams help us model.
Why Do State Diagrams Exist?
In the previous articles, we explored different perspectives of a software system.
- Class Diagrams helped us understand the structure.
- Sequence Diagrams showed how objects collaborate.
- Use Case Diagrams captured what users want to accomplish.
But there's still one question left unanswered.
How does an object change throughout its lifetime?
Some objects are simple.
A Country rarely changes.
Others are constantly evolving.
Think about:
- an Order
- a Payment
- a Ride
- a Booking
- a Support Ticket
Their behavior depends entirely on their current state.
A customer can cancel an order before it is shipped.
Not after it has been delivered.
The system needs a way to model these business rules.
That's the purpose of a State Diagram.
What Is a State Diagram?
A State Diagram models the lifecycle of a single object.
Instead of showing interactions between multiple objects, it focuses on one question:
What states can this object be in, and how does it move between them?
Think of it as a roadmap for an object's life.
Every important business object follows one.
Understanding States
A state represents a condition that an object is currently in.
Consider an online order.
Created
Confirmed
Paid
Shipped
Delivered
Cancelled
At any given moment, the order exists in exactly one of these states.
Its current state determines what actions are allowed.
Transitions
Objects don't remain in the same state forever.
They move from one state to another.
These movements are called transitions.
Created
│
▼
Confirmed
│
▼
Paid
│
▼
Shipped
│
▼
Delivered
A transition represents change.
Something happens.
The object's status evolves.
Events Trigger Transitions
Objects don't change state randomly.
Something causes the transition.
These triggers are called events.
For example:
Created
│
(payment succeeds)
▼
Paid
or
Ride Requested
│
(driver accepts)
▼
Driver Assigned
Events are the bridge between user actions and business behavior.
A Real-World Example: Online Shopping
Let's look at the complete lifecycle of an order.
Created
│
▼
Confirmed
│
▼
Paid
│
▼
Packed
│
▼
Shipped
│
▼
Delivered
Now let's think about cancellations.
Should a customer be able to cancel at every stage?
Probably not.
Maybe cancellation is allowed only before shipping.
That business rule naturally becomes part of the state model.
Created
│
├────────► Cancelled
│
Confirmed
│
├────────► Cancelled
│
Paid
│
├────────► Cancelled
│
Packed
│
Shipped
│
Delivered
Notice something important.
The diagram isn't just showing states.
It's expressing business policy.
Another Example: Ride Sharing
Now consider a ride-sharing platform.
A ride may move through these states.
Requested
│
▼
Driver Assigned
│
▼
Driver Arriving
│
▼
Ride Started
│
▼
Ride Completed
Cancellation might be allowed here.
Requested
│
├────────► Cancelled
│
Driver Assigned
│
├────────► Cancelled
But once the ride has started, cancellation rules become completely different.
The current state determines the allowed actions.
Payment Is Also a Lifecycle
Many beginners think payment has only two outcomes.
Success or failure.
Real systems are far more nuanced.
Initiated
│
▼
Pending
├────────► Failed
│
└────────► Successful
│
▼
Refunded
Now think about the business rules.
Can a failed payment be refunded?
No.
Can a successful payment fail afterward?
No.
The state machine prevents these impossible scenarios.
Why Business Rules Belong Here
State Diagrams are often where business rules become visible.
For example:
Order Delivered
│
▼
Cancel Order
Should this transition exist?
Probably not.
Instead:
Delivered
(No cancellation allowed)
Similarly:
Payment Failed
│
▼
Issue Refund
Again, that transition doesn't make sense.
By thinking in terms of states, invalid business behavior becomes much easier to detect.
State Diagrams Are Not Flowcharts
This is one of the most common misunderstandings.
A flowchart asks:
What steps does the process follow?
A State Diagram asks:
What condition is this object currently in?
These are very different questions.
A checkout process might involve dozens of steps.
The order itself may only transition through six or seven meaningful states.
Don't confuse process flow with object lifecycle.
Weak Thinking vs Strong Thinking
Weak Thinking
An order is just an object.
Strong Thinking
An order has a lifecycle,
and every action depends
on its current state.
Weak Thinking
Let's validate everything
inside the controller.
Strong Thinking
The object's current state
should determine what is allowed.
Weak Thinking
Every action is always available.
Strong Thinking
Available actions change
as the object evolves.
Common Beginner Mistakes
Mixing multiple objects
A State Diagram should describe one object's lifecycle.
Don't combine Orders, Payments, Deliveries, and Notifications into the same diagram.
Keep the focus clear.
Ignoring failure states
Many diagrams only show the happy path.
Real systems also have:
- failures
- cancellations
- retries
- expirations
- refunds
Ignoring these states often leads to incomplete designs.
Allowing impossible transitions
Ask yourself:
"Would this make sense in the real world?"
If not, it shouldn't appear in your State Diagram.
Thinking only about implementation
State Diagrams are primarily about business behavior.
Implementation comes later.
The business lifecycle should drive the code—not the other way around.
Interview Perspective
In Low-Level Design interviews, candidates often focus heavily on classes and APIs.
Strong candidates go one step further.
They ask questions like:
- What states can this object have?
- What transitions are allowed?
- What business rules prevent invalid transitions?
- What happens when something fails?
These questions demonstrate a deep understanding of real-world systems.
Interviewers appreciate candidates who naturally think in terms of object lifecycles because it shows they understand software beyond syntax.
The Most Important Insight
Every important business object has a lifecycle.
Understanding that lifecycle is often more valuable than understanding the code itself.
A well-designed system doesn't just know what objects exist.
It knows what those objects are allowed to become.
When you model state correctly, many business bugs disappear before a single line of code is written.
One-Line Takeaway
Great software doesn't just model objects—it models how those objects are allowed to evolve over time.
Top comments (0)