State pattern

State pattern

State pattern

Design pattern, which aims to facilitate the extension of the building of the new states. With the change of state is changing the behavior of object. States are temporary objects, they have a common interface and they are associated with a particular object(context).
We use it where we have a lot of conditional statements(eg. if / switch).
 state pattern
Context – class, which may have different states
State – defines a common interface for all states, so that they are interchangeable.
ConcreteState – defines a concrete definition of the state
Let’s see how it works on the example.

Example

At the beginning we implement context class which will be represented employee.

//context
public class Employee
{
    public Position _developer { get; set; }
    public string _name { get; set; }

    public Employee(string name)
    {
        _name = name;
        _developer = new JuniorDeveloper();
    }

    // calculation of salaries
    public void CalculateSalaray(int overtime)
    {
        _developer.CalculateSalaray(this, overtime);
    }

    // promotion
    public void Promote()
    {
        _developer.Promote(this);
    }
}

Our employee will be able to : calculation of salaries and can advance. OK but… what mean Position in this class.

So, position is state, which can be an interface or an abstract class. The status will vary depending on – in which state is our object.

//state
public interface Position
{
    void CalculateSalaray(Employee dev, int overtime);

    void Promote(Employee dev);
}

Let’s implement our states. Our states will pass in : Junior developer => Senior developer => Expert Developer =>can not be promoted above.

Let’s start with the fact that every employee starting from position Junior Developer. As we see it in the class of employee.
_developer = new JuniorDeveloper();
Suppose that junior earns 7000 and he gets 50 for overtime and he may be promoted to Senior.
//ConcreteState
public class JuniorDeveloper : Position
{
    int salary = 7000;
    public void CalculateSalaray(Employee dev, int overtime)
    {
        var result = 50 * overtime;
        var summarySalary = salary + result;
        Console.WriteLine(dev._name + "- current salary : " + summarySalary + " with " + overtime + " overtime");
    }

    public void Promote(Employee dev)
    {
        dev._developer = new SeniorDeveloper();
        Console.WriteLine(dev._name + " promoted to senior");
    }
}
 Senior earns 15000 and he gets 150 for overtime and he may be promoted to Expert
//ConcreteState
public class SeniorDeveloper : Position
{
    int salary = 15000;

    public void CalculateSalaray(Employee dev, int overtime)
    {
        var result = 150 * overtime;
        var summarySalary = salary + result;
        Console.WriteLine(dev._name + "- current salary : " + summarySalary + " with " + overtime + " overtime");
    }

    public void Promote(Employee dev)
    {
        dev._developer = new ExperDeveloper();
        Console.WriteLine(dev._name + " promoted to expert");
    }
}

Expert earns 90000 and he gets 600 for overtime and he can’t advance.

//ConcreteState
public class ExperDeveloper : Position
{
    int salary = 90000;

    public void CalculateSalaray(Employee dev, int overtime)
    {
        var result = 600 * overtime;
        var summarySalary = salary + result;
        Console.WriteLine(dev._name + "- current salary : " + summarySalary + " with " + overtime + " overtime");
    }

    public void Promote(Employee dev)
    {
        Console.WriteLine(dev._name + " can't advance");
    }
}

Let’s create objects of two workers Tom and Jessica.Both begin from the position Junior developer. Tom has 20 hours of overtime and Jessica has 12 hours of overtime per month.

So let’s see how our promotions(states) work
static void Main(string[] args)
{
    Employee john = new Employee("Tom");
    Employee katie = new Employee("Jessica");

    john.CalculateSalaray(20);
    katie.CalculateSalaray(12);

    Console.ReadKey();

    Console.WriteLine("\nJessica promotion");
    katie.Promote();
    john.CalculateSalaray(20);
    katie.CalculateSalaray(12);

    Console.ReadKey();

    Console.WriteLine("\nTom promotion");
    john.Promote();
    john.CalculateSalaray(20);
    katie.CalculateSalaray(12);

    Console.ReadKey();

    Console.WriteLine("\nTom promotion");
    john.Promote();
    john.CalculateSalaray(20);
    katie.CalculateSalaray(12);

    Console.ReadKey();

    Console.WriteLine("\nTom promotion");
    john.Promote();
    john.CalculateSalaray(20);
    katie.CalculateSalaray(12);

    Console.ReadKey();
}

Effect:

State pattern

Summary

Implemented state patter is practically easy. We can easily add another state, eg. Regular Developer without modifying code(like employee class).
This pattern works well where we use a lot of conditional statements like many if or switch.
It may be very simlilar to Strategy Pattern(post about it soon).Diferences are:
Stategy Pattern : we want to find a replacement for the inheritance

State Pattern : we want to find a replacement for a conditional statement if / switch.

 Link to project here

One Comment on “State pattern”

Leave a Reply

Your email address will not be published. Required fields are marked *