组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式结构图:
代码实现
Component 为组合中的对象声明接口,在适当的的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件
abstract class Component
{
protected string name;
public Component(string name)
{
this.name = name;
}
public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract void Display(int depth);
}Leaf在组合中表示叶节点对象,叶节点没有子节点。
class Leaf : Component
{
public Leaf(string name) : base(name)
{} public override void Add(Component c)
{
Console.WriteLine("cannot add to a leaf");
}
public override void Remove(Component c)
{
Console.WriteLine("cannot remove from a leaf");
}
public override void Display(int depth)
{
Console.WriteLine(new String('-',depth)+name);
}
}
Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加,删除
class Composite : Component
{
private List<Component> children = new List<Component>(); public Composite(string name) : base(name)
{
}
public override void Add(Component c)
{
children.Add(c);
}
public override void Remove(Component c)
{
children.Remove(c);
}
public override void Display(int depth)
{
Console.WriteLine(new String('-',depth)+name);
foreach(Component component in children)
{
component.Display(depth+2);
}
}}
---客户端代码 能通过Component接口操作组合部件的对象---
static void Main(string[] args)
{
Composite root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B")); Composite comp = new Composite("Component X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB")); root.Add(comp);
Composite comp2 = new Composite("Composite XY");
comp2.Add(new Leaf("Leaf XYA"));
comp2.Add(new Leaf("Leaf XYB"));
comp.Add(comp2);
root.Add(new Leaf("Leaf C")); Leaf leaf = new Leaf("Leaf D");
root.Add(leaf);
root.Remove(leaf);
root.Display(1); Console.Read();
}透明方式与安全方式
透明方式是子节点与叶节点都实现相同的接口,对有的方法对于叶节点没有意义而已,如果需要安全方式就在Component接口中不去声明方法,而在Composite中声明,但由于不够透明,树叶与树枝将不具有相同的接口,客户端调用需要做相应的判断,带来了不便。当需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,应该是考虑用组合模式。