组合模式 - Composite
2014-02-18 18:10
330 查看
组合模式(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中声明,但由于不够透明,树叶与树枝将不具有相同的接口,客户端调用需要做相应的判断,带来了不便。
当需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,应该是考虑用组合模式。
组合模式结构图:
代码实现
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中声明,但由于不够透明,树叶与树枝将不具有相同的接口,客户端调用需要做相应的判断,带来了不便。
当需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,应该是考虑用组合模式。
相关文章推荐
- 备忘录模式 - Memento
- 经典问题总结(一)
- pakage,import
- xjad一款不错的java反编译软件
- 适配器模式 - Adapter
- 初学Log4cxx的应用
- bzoj 2440 容斥原理
- discuz论坛发起活动插件的数据调用以及数据保存数据表。
- openstack 命令行管理二 - 镜像管理 (备忘)
- 状态模式 - State
- 马化腾:用户体验的10/100/1000法则
- Unity读取Android通讯录。
- 马化腾:用户体验的10/100/1000法则
- Seasar2框架:AOP
- 抽象工厂模式 - Abstract Factory
- 模拟航班查询-小程序
- POJ 3352 Road Construction (边双连通分量)
- HDOJ 2888 Check Corners
- 干IT,知识不更新,你就是在贬值
- Ext下解决无弹出窗口的设计解决办法