Let’s imagine that you have graph editor where you can paint different figures. Also you can move all figures, change their colors. And you shouldn’t know for these actions, what kind of object you use. It’s may be one circle or several figures, that you selected with mouse.
Composite pattern can organize this object set. One object or and set of several objects will have the same behavior.
Result of our class structure can be using very simple:
static void Main(string[] args)
{
var figure = new Figure() { Name = "Test figure" };
figure.ChildrenFigures.Add(new Point { Color = "Green" });
figure.ChildrenFigures.Add(new Line { Color = "White" });
var innerFigure = new Figure() { Name = "Inner figure" };
innerFigure.ChildrenFigures.Add(new Line { Color = "Yellow" });
innerFigure.ChildrenFigures.Add(new Line { Color = "Yellow" });
figure.ChildrenFigures.Add(innerFigure);
figure.ChildrenFigures.Add(new Point { Color = "Green" });
Console.WriteLine(figure);
}
Let’s create basic class and concrete classes, that will have the same actions, that doesn’t depended on what object it will be calling.
public class Figure
{
public int level = 0;
public virtual string Name { get; set; } = "Group";
public string Color { get; set; }
public List<Figure> ChildrenFigures = new List<Figure>();
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append($"{new String(' ', level * 5)}{Color}{Name}");
sb.Append(System.Environment.NewLine);
foreach (var f in this.ChildrenFigures)
{
f.level = this.level + 1;
sb.Append(f.ToString());
}
return sb.ToString();
}
}
public class Line : Figure
{
public override string Name { get; set; } = "Line";
}
public class Point : Figure
{
public override string Name { get; set; } = "Point";
}
Great! Our example is ready. We can use one or more figures and we can call ToString() method on our new objects.