组合对象数据结构:
UML类图:
实例实现代码:
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);
}
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);
}
}
}
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);
}
}
客户端实现:
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("Composite 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 :是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
Leaf :在组合中表示叶子结点对象,叶子结点没有子结点。
Composite: 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
在Cocoa Touch框架中使用组合模式:
UIView被组织成一个组合模式。每个UIView的实例可以包含UIView的其他实例,形成统一的树形结构。让客户端对单个UIView对象和UIView的组合统一对待。
视图组合参与绘图事件处理,当请求超视图为显示进行渲染时,消息会先在超视图被处理,然后传给其子视图,消息会传播到遍及整个树德其他子视图,因为它们都是相同的类型-UIView,他们可以被统一处理,而且UIView层次结构的一个分支也可以同样当做一个视图来处理。
统一的视图也作为一个响应者链,用于事件处理和动作消息。绘图消息像事件处理消息那样,顺着结构从超视图向子视图传递。
总结:
组合模式的主要意图就是让树形结构中的每个节点具有相同的抽象接口,这样整个结构可作为一个统一的抽象结构使用,而不暴露其内部表示。对每个节点(叶子节点或组合体)的任何操作,可以通过协议或者抽象基类中定义相同接口来进行。
对这个结构新增的操作可以用访问者模式来实现,让访问者访问每一节点进行进一步的处理,而不必修改现有的组合结构。
组合结构的内部表示不应该暴露给客户端,因此组合模式总是跟迭代器模式一起使用,以遍历组合对象中的每个项目。
参考资料
-《大话设计模式》-《Objective-C编程之道》