State pattern vs ENUM

Typically the ENUM approach involves some sort of a table (array) of states and transitions. Whereas the design pattern achieves the same with objects.

If you arent referring to the table approach with ENUMs, then the solution would need to involve a large if/else if block, which is quite unmanageable. Referring to the section below, I think its quite obvious this particular solution is inferior.

Here are what I would list as PROs and CONs of each

ENUM table

PROs:

  • Easier to see all of the states and transitions since the table is defined in one place

CONs:

  • States and transitions are more hard-coded and more code changes are needed to extend

Design Pattern

PROs:

  • Easier to extend with new states by adding a new object. (Open/Close Principle)
  • Easier to assure that all signals are treated by the states, since the base class should define the signals as abstract functions.
  • Easier to extend a particular states' behavior by deriving from the state. The state pattern should put a particular state's behavior in one object.

CONs:

  • More difficult to see all states and their relations by looking at code, since they are dispersed among several different classes.
  • Could end up creating an unmanageable number of objects. But compare this to the corresponding if/else blocks needed with the corresponding ENUM solution.

Why do we use State pattern? To remove conditional logic duplication, and replace conditional code with polymorphism.

When do we have conditional logic duplication? When we have many actions, which depend on state, thus you have to duplicate your conditional logic in every action. It becomes very annoying when you have many states. Also code duplication means that you should update every copy of duplicated code when you are adding new states.

So, if I don't have duplicated conditional logic, I'd rather go with enum-based state, instead of creating new class hierarchy with many classes for states. Sometimes I even prefer conditional logic duplication: e.g. when I have many states, but only few state-dependent actions. In this case I prefer to have two switch blocks instead of creating ten new classes.