8/10/10

The State Design Pattern

Sometime ago I was given the task of designing a module for creating and managing work orders for one of our clients. For those of you wondering what a work order is..let me give you an example..

Let's say you live in an apartment and your air conditioning system is not working. what do you do? You immediately call up the apartment office to report it. So what you are doing is initiating a work order process. The office assistant takes your request and creates a work order for repairing the a/c. This work order is then sent to a technician who sends an estimate to the assistant. The assistant or the assistant's supervisor approves the cost estimate and the technician gets to work. The technician completes the job and reports back to the assistant. The assistant then closes the work order(after confirming with you obviously). This is a typical work order workflow process.

I had to develop a user interface to facilitate this entire process. I decided to browse through the GoF design patterns to see if I could find some pattern that would serve the purpose. I obviously ruled out the creational and structural patterns since I was not looking along those lines. So I started looking at the behavioral patterns wherein I came across the State Design Pattern. After carefully studying the pattern I decided that I was going to go with it.

Why the State Design Pattern?
The work order process goes through different stages and the behavior changes at every step. It is the same work order that appears to take on different forms at different stages. We can use a single object and keep altering it's underlying behavior with every step in the work flow process. We can tie the user interface to the underlying behavioral changes so that, as the flow changes, the UI will also change accordingly.

The UML is as follows:

















How it works:
  • The UI interacts with the State Manager which is the object that changes it's underlying behavior
  • The State Manager changes it's underlying behavior through an instance of  the Abstract State class, which happens to be one of its member fields.
  • This instance points to a different concrete instance of type State at different stages of the work order process. As this happens, it appears as if the State Manager is changing it's underlying behavior.
  • The UI also changes from step to step depending on the properties of the State Manager.

 Code:

public class WorkOrderUI: System.Web.UI.Page
{
   StateManager objStateManager;
   protected void Page_Load(object sender, EventArgs e)
  {
     objStateManager = new StateManager();
     DisplayUI();
   }
  
/*render the UI depending on the state manager's underlying state*/
private void DisplayUI()
{
    if(objStateManager.IsApproved) //do so and so
      btnApprove.visible = false;
}

  /*save handler, calls the statemanager that will change it    behavior as a result of this save*/
   protected void Save(object sender, EventArgs e)
  { 
     objStateManager.SaveState();
   }
}

public class StateManager
{
   State objState;
   public StateManager()
  {    
     objState = GetState();
  }

 private State GetState()
{
  /*depending on various properties this method returns the current state*/
   return new WorkOrderState();//example
}

public void SaveState()
{
   //saves state
    objState.SaveData();
}

}

public abstract class State
{
   protected abstract State GetData();
   protected abstract void SaveData();
}

public class WorkOrderRequest:State
{
   protected State GetData()
  {
     //implement functionality specific to this state
   }

  protected void SaveData()
  {
     //implement the save specific to this state
  }
}

other state classes are implemented in a similar manner.

No comments: