State
- Allows an object to behave differently when it states changes
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
Example Code