(一)定义:组合多个对象形成树形结构以表示为“部分--整体”的结构层次。组合模式使得用户对单个对象和组合对象的使用具有一致性。
1.1 UML类图:
![image image](https://images2017.cnblogs.com/blog/329170/201709/329170-20170907164105944-379644628.png)
1.2 类与对象间的关系
Component:部件抽象接口。
① 为组合的对象声明接口。
② 某些情况下,实现从此接口派生出所有类共有的默认行为。
③ 定义一个接口可以访问及管理它的多个子部件(GetChild)。
④ 如果必要,也可以在递归结构中定义一个接口访问它的父节点,并且实现它。
Leaf:叶部件
① 在组合中表示叶节点对象,叶节点没有子节点。
② 定义组合中原接口对象的行为。
Composite:组合类
① 定义有儿子节点(子部件)的部件的行为
② 存储儿子节点(子部件)
③ 在Component接口中实现与子部件相关的操作
典型调用顺序图
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
组合模式-源码public 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);
}
public class Leaf : Component
{
public Leaf(string name)
: base(name)
{
}
public override void Add(Component c)
{
Console.WriteLine("不能添加到叶子节点");
}
public override void Remove(Component c)
{
throw new NotImplementedException();
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
}
}
public 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 c in children)
{
c.Display(depth + 2);
}
}
}
public class Client
{
private Composite root = new Composite("root");
public Client()
{
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);
}
public void Print()
{
root.Display(1);
}
}
源码分析:
![123 123](https://images2017.cnblogs.com/blog/329170/201709/329170-20170907115633038-292812756.gif)
![2017-09-07_115208 2017-09-07_115208](https://images2017.cnblogs.com/blog/329170/201709/329170-20170907115758538-815453871.jpg)
(二) 项目案例分析 源码下载
案例描述:假设某个公司的OA系统要计算员工和部门工资。部门有部门主管,其他下有多名员工。既要计算个体员工工资,又要计算部门开支公司。图形如下
![1111 1111](https://images2017.cnblogs.com/blog/329170/201709/329170-20170907164029554-512058711.gif)