组合模式允许将对象组合成树形结构来表达”部分-整体“层次结构,使客户端程序可以以相同的方式来处理单独对象以及复杂对象(多个单独对象的组合)。
客户端程序可以像处理简单元素一样来处理复杂元素,使客户端程序与复杂元素的内部结构解耦。
组合模式涉及到三个角色:
抽象构件、树叶构件、树枝构件
案例:
复杂图形:圆、线的组合
简单图形:圆、线
一、透明式的组合模式
// 通过一些简单图形以及一些复杂图形构建图形树来演示组合模式
// 客户端调用
class Client
{
static void Main(string[] args)
{
ComplexGraphics complexGraphics = new ComplexGraphics("一个复杂图形和两条线段组成的复杂图形");
complexGraphics.Add(new Line("线段A"));
ComplexGraphics CompositeCG = new ComplexGraphics("一个圆和一条线组成的复杂图形");
CompositeCG.Add(new Circle("圆"));
CompositeCG.Add(new Circle("线段B"));
complexGraphics.Add(CompositeCG);
Line l = new Line("线段C");
complexGraphics.Add(l);
// 显示复杂图形的画法
Console.WriteLine("复杂图形的绘制如下:");
Console.WriteLine("---------------------");
complexGraphics.Draw();
Console.WriteLine("复杂图形绘制完成");
Console.WriteLine("---------------------");
Console.WriteLine();
// 移除一个组件再显示复杂图形的画法
complexGraphics.Remove(l);
Console.WriteLine("移除线段C后,复杂图形的绘制如下:");
Console.WriteLine("---------------------");
complexGraphics.Draw();
Console.WriteLine("复杂图形绘制完成");
Console.WriteLine("---------------------");
Console.Read();
}
}
/// <summary>
/// 图形抽象类,
/// </summary>
public abstract class Graphics
{
public string Name { get; set; }
public Graphics(string name)
{
this.Name = name;
}
public abstract void Draw();
public abstract void Add(Graphics g);
public abstract void Remove(Graphics g);
}
/// <summary>
/// 简单图形类——线
/// </summary>
public class Line : Graphics
{
public Line(string name)
: base(name)
{ }
// 重写父类抽象方法
public override void Draw()
{
Console.WriteLine("画 " + Name);
}
// 因为简单图形在添加或移除其他图形,所以简单图形Add或Remove方法没有任何意义
// 如果客户端调用了简单图形的Add或Remove方法将会在运行时抛出异常
// 我们可以在客户端捕获该类移除并处理
public override void Add(Graphics g)
{
throw new Exception("不能向简单图形Line添加其他图形");
}
public override void Remove(Graphics g)
{
throw new Exception("不能向简单图形Line移除其他图形");
}
}
/// <summary>
/// 简单图形类——圆
/// </summary>
public class Circle : Graphics
{
public Circle(string name)
: base(name)
{ }
// 重写父类抽象方法
public override void Draw()
{
Console.WriteLine("画 " + Name);
}
public override void Add(Graphics g)
{
throw new Exception("不能向简单图形Circle添加其他图形");
}
public override void Remove(Graphics g)
{
throw new Exception("不能向简单图形Circle移除其他图形");
}
}
/// <summary>
/// 复杂图形,由一些简单图形组成,这里假设该复杂图形由一个圆两条线组成的复杂图形
/// </summary>
public class ComplexGraphics : Graphics
{
private List<Graphics> complexGraphicsList = new List<Graphics>();
public ComplexGraphics(string name)
: base(name)
{ }
/// <summary>
/// 复杂图形的画法
/// </summary>
public override void Draw()
{
foreach (Graphics g in complexGraphicsList)
{
g.Draw();
}
}
public override void Add(Graphics g)
{
complexGraphicsList.Add(g);
}
public override void Remove(Graphics g)
{
complexGraphicsList.Remove(g);
}
}
二、安全式的组合模式
/// <summary>
///安全模式将复杂类型种特有的属性从父类种抽出来到复杂类型种
/// </summary>
class Cliet
{
static void Main(string[] args)
{
Console.WriteLine("开始绘制负责图形");
var complexG = new ComplexGraphics("一个圆两条线");
complexG.Add(new Circle("圆"));
complexG.Add(new Line("线1"));
complexG.Add(new Line("线2"));
complexG.Draw();
Console.WriteLine("复杂图形绘制完毕");
Console.ReadKey();
}
}
public abstract class Graphics
{
public string Name { get; set; }
public Graphics(string name) {
this.Name = name;
}
public abstract void Draw();
//public abstract void Add();
//public abstract void Remove();
}
public class Circle : Graphics
{
public Circle(string name) : base(name)
{
}
public override void Draw()
{
Console.WriteLine($"This is {Name}");
}
}
public class Line : Graphics
{
public Line(string name) : base(name)
{
}
public override void Draw()
{
Console.WriteLine($"This is {Name}");
}
}
public class ComplexGraphics : Graphics
{
private List<Graphics> graphicList = new List<Graphics>();
public ComplexGraphics(string name) : base(name) { }
public override void Draw()
{
foreach(var graphic in graphicList)
{
graphic.Draw();
}
}
public void Add(Graphics graphic)
{
if (graphic!=null)
{
graphicList.Add(graphic);
}
}
public void Remove(Graphics graphic)
{
if (graphicList.Contains(graphic))
{
graphicList.Remove(graphic);
}
}
}