Design Patterns

Last Updated: 9/25/2024

State

  • Allows an object to behave differently when it states changes

Classical Structure

State Classical Structure

Scenario

  • Build a drawing app like photoshop. Canvas behaves differently depending on the selected tool

Problem

  • Duplicate code in mouseDown, mouseUp, keyDown and keyUp. Code is not maintainable
  • Code is not extensible
  • Violates Open Closed Principle
public enum ToolType
{
    SELECTION,
    BRUSH,
    ERASER
}
public class Canvas
{
    public ToolType CurrentTool {  get; set; }

    public void MouseDown()
    {
        if (CurrentTool == ToolType.SELECTION)
            Console.WriteLine("Selection Icon");
        else if (CurrentTool == ToolType.BRUSH)
            Console.WriteLine("Brush Icon");
        else if (CurrentTool == ToolType.ERASER)
            Console.WriteLine("Eraser Icon");
    }

    public void MouseUp()
    {
        if (CurrentTool == ToolType.SELECTION)
            Console.WriteLine("Draw dashed rectangle");
        else if (CurrentTool == ToolType.BRUSH)
            Console.WriteLine("Draw a line");
        else if (CurrentTool == ToolType.ERASER)
            Console.WriteLine("Eraser something");
    }
}

Solution

public interface ITool
{
    void MouseDown();
    void MouseUp();
}
public class SelectionTool : ITool
{
    public void MouseDown()
    {
        Console.WriteLine("Selection Icon");
    }

    public void MouseUp()
    {
        Console.WriteLine("Draw dashed rectangle");
    }
}
public class BrushTool: ITool
{
    public void MouseDown()
    {
        Console.WriteLine("Brush Icon");
    }

    public void MouseUp()
    {
        Console.WriteLine("Draw a line");
    }
}
public class Canvas
{
    public ITool CurrentTool { get; set; }

    public void MouseDown()
    {
        CurrentTool.MouseDown();
    }

    public void MouseUp()
    {
        CurrentTool.MouseUp();
    }
}
public class Program
{
    static void Main(string[] args)
    {
	    var canvas = new Canvas();
		canvas.CurrentTool = new BrushTool();
		canvas.MouseDown();
		canvas.MouseUp();
    }
}    

Example Structure

State Example Structure

Example Code