In order state example I would like to demonstrate that there are more then one solution of domain problem of order state which can transition into another states.
There are public constants on class and you should figure out that you should put them into canDoTransition()
method. There is nothing on type-level that helps you with that. Please note that all logic is in OrderService
.
This test shows usage of explicitly-declared dumb-enum.
I have explicitly declared type for OrderState
. It is not possible anymore to pass non-sense values into OrderService
. That is because OrderState
enum provides no interface for creating non-sense values. So they simply cannot exists.
All logic has been kept in OrderService
. We still need to handle cas when someone added new value to enum, which we do not count with. (the exception in default case).
Here I have moved OrderService::canDoTransition()
method into enum itself.
Nice thing is that we do not need anymore external service for asking OrderState
-related questions.
Remaining problem is that there are still lot of ifs and we still need to handle case where someone adds new value into enum which we do not count with.
When there is behaviour same for all values of enum, it can be safely placed on enum class. Behaviour can be parametrized by providing necessary information in enum-value constructor.
Now, new domain requirement:
I would like to remove person who has been assigned to work on order, when order changes state to cancelled or finished.
- I have rewritten each value as separate class (as behaviour is different for different values)
- I have implemented doTransition() on enum parent class as it is only proper way of changing enum value
- I have added
onActivation(Order $order)
method, which is called whenever state transition occurs. - I have overridden
onActivation()
on enum values with desired behaviour.