组合模式(Composite): 将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性
Component 为组合中的对象什么接口,在适当情况下,实现所有类共有接口的默认行为。 声明一个接口用于访问和管理 Component 的子部件
abstract class Component{
protected string name;
ppublic 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 Left :Compinent{
public Left(string name) : base(name){
}
public override void Add(Component c){ //由于叶子节点没有再增加分支和树叶,所以Add 和Remove方法实现它没有意义,但这样做可以消除叶节点和支节点对象在抽象层次的区别,它们具备完全一致的接口
Console.WriteLine("Cannot add to left");
}
public override void Remove(Component c){
Console.WriteLine("Cannot remove from a left");
}
public override void Display(int depth){ //叶节点的具体表示方法, 此处是显示具体名称和级别
Console.WritrLine(new String ('-', depth) + name);
}
}
Composite: 定义有枝节点行为, 用来存储子部件, 在Composite 接口中实现与子部件有关的操作, 比如增加Add 和删除 Remove.
class Composite : Component{
private List<Component> children = new List<Component>(0); //一个子对象集合用来存储其下属的枝节点和叶节点
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 ,根上长出两叶LeftA 和 LeftB
root.Add(new Leaf("Left A"));
root.Add(new Leaf("Left B"));
Composite comp = new Composite("Composite X"); //根上长出分枝Composite X,分枝上也有两叶LeafXA 和LeafXB
comp.Add(new Left("Left XA"));
comp.Add(new Left("Left XB"));
root.Add(comp);
Composite comp2 = new Composite("Composite XY"); //在Composite X上在长出分枝 CompositeXY ,分枝上也有两叶LeafXYA 和LeafXYB
comp2.Add(new Leaf("Leaf XYA"));
comp2.Add(new Leaf("Leaf XYB"));
comp.Add(comp2);
root.Add(new Left("Leaf C")); //根部有长出两叶 LeafC 和 LeafD, 可惜LeafD 没长牢,被风吹走了
Leaf leaf = new Leaf("Leaf D")
root.Add(leaf);
root.Remove(leaf);
root.Display(1); //显示大树的样子
Consple.Read();
}
何时使用组合模式:
需求中是体现部分与整体层次的结构时,以及你希望以后可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时, 就应该考虑组合模式。
组合模式的好处:
组合模式定义了包含基本对象和组合对象的类层次结构。基本对象可以被组合成更复杂的组合对象, 而这些组合对象又可以被组合, 这样不断地递归下去, 客户代码中, 任何用到基本对象的地方都可以使用组合对象了。
用户是不用关心到底是处理一个叶节点还是处理一个组合组件, 也就用不着为定义组合而写一些选择判断语句了。
组合模式让客户可以一致地使用组合结构和单个对象。