State Pattern

The state pattern is a behavioral pattern that allows an object to partially change its type at runtime.  This is useful in situations where we can not change the type of a base object, but wish to represent the state of it in encapsulated classes.

Let us consider a payroll system where employees are compensated and promoted based upon their current position. 
We could use a property to store the employees current position.

    public class Employee
{
public string Name { get; set; }

public EmployeePosition Position { get; set; }

public void Promote()
{
switch (Position)
{
case EmployeePosition.JuniorDeveloper:
Position = EmployeePosition.SeniorDeveloper;
break;
case EmployeePosition.SeniorDeveloper:
Position = EmployeePosition.TechnicalLead;
break;
case EmployeePosition.TechnicalLead:
// This is as high as it goes.
break
;
}
}

public void Compensate(Accounting accounting)
{
int salary = 0;

switch (Position)
{
case EmployeePosition.JuniorDeveloper:
salary = 40000;
break;
case EmployeePosition.SeniorDeveloper:
salary = 75000;
break;
case EmployeePosition.TechnicalLead:
salary = 100000;
break;
}

accounting.Pay(this, salary);
}
}

public enum EmployeePosition
{
JuniorDeveloper,
SeniorDeveloper,
TechnicalLead
}

public class Accounting
{
public void Pay(Employee employee, int dollars)
{
// Pay the employee
}
}
This code is brittle.  Changing the EmployeePosition enum requires changing multiple methods in the Employee domain object.  The logic is spread thin and the encapsulation is non-existent.

A Better Way

A better way to do this is to use the state pattern.  With the state pattern, the EmployeePosition enum is replaced by an abstract class representing the employees current position.
    public abstract class AbstractEmploymentState
{
private readonly Employee employee;

public AbstractEmploymentState(Employee employee)
{
this.employee = employee;
}

protected virtual Employee Employee { get { return employee; } }

public abstract void Promote();

public abstract void Compensate(Accounting accounting);
}

public class Employee
{
private AbstractEmploymentState employmentState;
public string Name { get; set; }

public AbstractEmploymentState EmploymentState
{
get { return employmentState; }
set { employmentState = value; }
}

public void Promote()
{
EmploymentState.Promote();
}

public void Compensnate(Accounting accounting)
{
EmploymentState.Compensate(accounting);
}
}

public class JuniorDeveloperState: AbstractEmploymentState
{
public JuniorDeveloperState(Employee employee) : base(employee)
{
}

public override void Promote()
{
Employee.EmploymentState = new SeniorDeveloperState(Employee);
}

public override void Compensate(Accounting accounting)
{
accounting.Pay(Employee, 40000);
}
}

public class SeniorDeveloperState: AbstractEmploymentState
{
public SeniorDeveloperState(Employee employee) : base(employee)
{
}

public override void Promote()
{
Employee.EmploymentState = new TechinicalLeadState(Employee);
}

public override void Compensate(Accounting accounting)
{
accounting.Pay(Employee, 75000);
}
}

public class TechinicalLeadState: AbstractEmploymentState
{
public TechinicalLeadState(Employee employee) : base(employee)
{
}

public override void Promote()
{
// Do Nothing, this is as high as it goes for now.
}
 
public override void Compensate(Accounting accounting)
{
accounting.Pay(Employee, 100000);
}
}

public class Accounting
{
public void Pay(Employee employee, int dollars)
{
// Pay the employee
}
}
In this example, employees are compensated and promoted based upon their positions.  The domain object, Employee, delegates these actions to the AbstractEmploymentState object. 

Note how simplified the Promote and Compensate methods of Employee are:
        public void Promote()
{
EmploymentState.Promote();
}

public void Compensate(Accounting accounting)
{
EmploymentState.Compensate(accounting);
}
Adding a new state, or increasing the complexity of the logic involved in compensation and promotion of the Employees is encapsulated, leaving the design flexible.

Polymorphic Employee

Ok, so polymorphism is good.  Every OO programmer knows that, right?  So why don't we just make the Employee class polymorphic with subclasses for each position i.e. JuniorDeveloper, SeniorDeveloper, and TechnicalLead are all classes that inherit from Employee and implement the appropriate Compensate and Promote logic.

In this case, implementing the promote logic in the subclasses would be quite challenging as we can not change the type of a class at runtime.  It could be done by changing the Promote method signature to return an Employee.  The subclasses could then each implement Promote that returned an appropriate subclass of employee.  However, this solution feels contrived.  It is also more difficult to understand for a future maintenance programmer and could lead to hard to find bugs.

Another reason we may not wish to have a polymoprhic Employee class is because there may be multiple state objects in a single domain object.  What if we need not only to compensate and promote employees based upon their position, but also to assign vacation days based upon the project to which the empoloyee is currently assigned?  A situation where we needed a class for TechnicalLeadWhoIsWorkingOnProjectX arises.

Another reason to use the state pattern instead of full blown polymoprhism of the domain object is when using an ORM such as NHibernate.  NHibernate with Single Table Inheritance does not make it easy to change the type of a persistent object.  You can do with with SQL, but it's a clumbsy solution. 

Conclusions

The state pattern is a useful tool in a programmer's swiss army knife of design patterns.  It can help you avoid ugly switch statements and encapsulate domain logic in a flexible manner.

kick it on DotNetKicks.com