- This is a bad example. All it did was move the implementation of multiple behaviors (calls, messages, alarms, notifications) into each of the state instances.
A better way to handle this is to separate policy and mechanism. The state has configuration about handling of (calls, messages, alarms, notifications), and when each thing needs to be done that call/message/etc config is requested from the state and processed uniformly from there on out, not by the phone nor the state but by the call/message/etc handler.
- This is a domain modeling question.
If your if-else branches and flags are creating a combinatorial explosion and/or allowing more states to exist than are valid, pay the complexity tax of introducing a State pattern - it will pay itself back in maintainability and lack of bugs over time.
But if you’re just talking about one or two standalone values, the state is already there, represented as simply as possible by your enums.
- Turning if statements into a collection of classes requires a bit more thoughts than "Stop Writing If-Else Trees"
Sometimes the State pattern transforms "one big if-else tree" into "a forest of tiny classes" with its own complexity tax. Good design isn't about eliminating conditionals — it's about putting them where they make the most sense.
The real skill is knowing when your state transitions are complex enough to warrant the abstraction overhead.
- I sort of agree. I think that rather than develop that skill, many programmers just don’t care and add another “if”. The default I’ve seen is not a forest of classes but a warren of conditional logic.
Conditional logic falls into 3 categories, more or less:
1. Algorithms 2. Validation 3. Type replacements
It’s the third that is most common, and always “wrong”. Sometimes it’s better to keep conditional logic rather than try and figure out the correct type modeling. But most often, the programmer reaching for “if” isn’t even aware of what they are doing. They have a hammer, and everything looks like a nail.