A Study in Patterns: The State Pattern
I'm a big fan of software development patterns. They're an excellent way to get the ball rolling when you're faced with a puzzling design situation. But sometimes they're difficult to grok and it can be confusing to know when and how to implement just the right pattern for the circumstance. So to improve my own skill and knowledge with patterns I'm going to start a series of posts exploring some useful patterns - undoubtedly these posts will be as much for me as anyone who reads them.
One of the patterns I've recently found useful is the State Pattern. If you've ever used an enumeration to define or transition an object's state, or written an elaborate switch statement with nested "if" blocks to modify an object's behavior depending on its state then the State Pattern might be right up your ally. The GoF defines the State Pattern as:
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
This definition is all well and good (and I might argue with the "change its class" business), but how would you actually implement such magic. Let's use the following model as an example:
The basic premise is that we hide changes in our implementation of methods like "Graduate" and "IssueTranscript" behind the private field "_state" which is a reference to an IStudentState. Our public methods Student.Graduate() and Student.IssueTranscript() call the implementations of _state.Graduate() and _state.IssueTranscript(). If _state happens to be an instance of ApplicationState then IssueTranscript() will likely perform a different action than if _state was a GraduatedState.
Another thing you'll notice is the reference that the "state" classes have back to Student. There are likely alternate implementations of this pattern that avoid this backward reference, but you might find that you need some context in your implementation methods within the state classes.
So you can begin to see how this can reduce the amount of complex switch/if logic you'll have. It may seem like it adds complexity in that you have more classes to content with, but after using this pattern a few times you'll be grateful of the clean segregation of behaviors achieve with the State Pattern.
