一、 合成(Composite)模式
合成模式有时又叫做部分-整体模式(Part-Whole)。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。
合成模式可以使客户端将单纯元素与复合元素同等看待。
从和尚的故事谈起
这是小时候我奶奶讲的故事:从前有个山,山里有个庙,庙里有个老和尚在给小和尚讲故事,讲的什么故事呢?从前有个山,山里有个庙……。奶奶的故事要循环多少次,根据你多长时间睡着而定。在故事中有山、有庙、有和尚、有故事。因此,故事的角色有两种:一种里面没有其它角色;另一种内部有其它角色。
二、 合成模式概述
- 抽象构件(Component)角色:这是一个抽象角色,它给参与组合的对象规定一个接口。这个角色给出共有接口及其默认行为。
- 树叶构件(Leaf)角色:代表参加组合的树叶对象。一个树叶对象没有下级子对象。
- 树枝构件(Composite)角色:代表参加组合的有子对象的对象,并给出树枝构件对象的行为。
////// 结构模式(Structural Pattern) /// 合成(Composite)模式 /// 合成模式有时又叫做部分-整体模式(Part-Whole)。 /// 合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。 /// 合成模式可以使客户端将单纯元素与复合元素同等看待。 /// class Program { ////// 异议 /// /// static void Main(string[] args) { // 创建一个树结构 CompositeElement roots = new CompositeElement("Picture"); roots.Add(new PrimitiveElement("Red Line")); roots.Add(new PrimitiveElement("Blue Circle")); roots.Add(new PrimitiveElement("Green Box")); CompositeElement comps = new CompositeElement("Two Circles"); comps.Add(new PrimitiveElement("Black Circle")); comps.Add(new PrimitiveElement("White Circle")); roots.Add(comps); // 添加和删除PrimitiveElement PrimitiveElement ls = new PrimitiveElement("Yellow Line"); roots.Add(ls); roots.Remove(ls); // 递归地显示节点 roots.Display(1); Console.ReadLine(); } } ////// 抽象构件(Component)角色 /// public abstract class DrawingElement { // 字段 protected string name; // 构造函数 public DrawingElement(string name) { this.name = name; } // 方法 abstract public void Display(int indent); } ////// 树枝构件(Composite)角色 /// public class CompositeElement : DrawingElement { private ArrayList elements = new ArrayList(); // 构造函数 public CompositeElement(string name) : base(name) { } // 方法 public void Add(DrawingElement d) { elements.Add(d); } public void Remove(DrawingElement d) { elements.Remove(d); } public override void Display(int indent) { Console.WriteLine(new String('-', indent) + "+ " + name); // 显示每个子元素节点 foreach (DrawingElement c in elements) { c.Display(indent + 2); } } } ////// 树叶构件(Leaf)角色 /// public class PrimitiveElement : DrawingElement { // 构造函数 public PrimitiveElement(string name) : base(name) { } // 从写函数 public override void Display(int indent) { Console.WriteLine(new String('-', indent) + " draw a {0}", name); } }