I have been busy for a while writing my two books about MVVM and WPF but I am almost done so be ready to get more posts in the next months. This one is the first of a series that I will write to solve the state pattern issue.
Today I want to start to talk about the state pattern, a design pattern used to represent the state of an object and how we can apply this pattern in a normal WPF application.
The problem we have is that based on the state of an Order we can or we cant execute a specific action.
Before starting to talk about the pattern we need a sample application, right? So, what is better than having a nice WPF application that we will use to represents the problem?
Process an order using States
The example I want to use is the classic Order entity that during the order process can be moved to different states. The following diagram create with Visual Studio shows you what I am talking about:
The previous image shows the state diagram applied to an Order:
- You can create an order and after it is created the state is of type Created
- Then you can modified the order or you can cancel the order; if you cancel the order, its state is cancelled and you cant do anything anymore
- An order that has been created can be approved and its state will change to approved
So in the previous Use Case we have identified 4 actions (blue) and 3 states (white), for each action there is a specific state, in a specific state you can execute only a specific or a set of specific actions and from one state you can move only to one or more specific states. For instance, from the Approved state we cant rollback to the Created state and so on
Now, how would you express the previous diagram using a Domain Model composed by an Order entity and a State property? First thing first is to implement a Domain Entity.
Now we can implement the classic state pattern described by Martin Fowler.
Classic implementation of the State Pattern
If you are an MVVM developer you may believe that the first and almost the easiest way of implementing this pattern is to use the Command pattern, right? So, if we plan to extend that in the Order entity we should have a model like the following one:
Where the command implementation may be something like this:
When an order is created, by default, we do not allow any state so the default state is undefined and these are the tests:
The last step needs to verify that if we try to move from one state to a not allowed state, the action that we try to execute will throw an exception:
Conclusion using the Classic method
This technique is not clean and it is very verbose but it is absolutely testable, but not maintainable. For instance, if the number of state enum will increase we have to touch all over the code that execute the flow logic and probably we need also to refactor all the commands so we can say that this solution is fine but not maintainable at all.
Another gap of this solution is that every time we want to execute a command we need to fire the CanExecute method that may process some long running business logic behind:
In the next blog post we will see a different approach. At the end of the series (04 posts) I will provide a WPF application on www.codeplex.com with the source code posted in this series; please be patient for now as I cant upload the final source code yet.