一、组合模式简介(Brief Introduction)
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
解决整合与部分可以被一致对待问题。
1、组合模式结构
Component类:组合中的对象声明接口,在适当情况下,实现所有类共有接口的行为。声明一个接口用于访问和管理Component的子部件
Leaf类:叶节点对象,叶节点没有子节点。由于叶节点不能增加分支和树叶,所以叶节点的Add和Remove没有实际意义。
有叶节点行为,用来存储叶节点集合
Composite类:实现Componet的相关操作,比如Add和Remove操作。
children:用来存储叶节点集合
2、源代码
1、抽象类Component
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 Diaplay(int depth);
}
2、叶子节点Leaf 继承于Component
public class Leaf:Component
{
public Leaf(string name)
:base(name)
{
}
public override void Add(Component c)
{
Console.WriteLine("不能向叶子节点添加子节点");
}
public override void Remove(Component c)
{
Console.WriteLine("叶子节点没有子节点");
}
public override void Diaplay(int depth)
{
Console.WriteLine(new string('-',depth)+name);
}
}
3、组合类Composite继承于Component,拥有枝节点行为
public class Composite : Component
{
List
children;
public Composite(string name)
:base(name)
{
if (children == null)
{
children = new List();
}
}
public override void Add(Component c)
{
this.children.Add(c);
}
public override void Remove(Component c)
{
this.children.Remove(c);
}
public override void Diaplay(int depth)
{
Console.WriteLine(new String('-',depth)+name);
foreach (Component component in children)
{
component.Diaplay(depth + 2);
}
}
}
4、客户端代码
static void Main(string[] args)
{
Composite root = new Composite("根节点root");
root.Add(new Leaf("根上生出的叶子A"));
root.Add(new Leaf("根上生出的叶子B"));
Composite comp = new Composite("根上生出的分支CompositeX");
comp.Add(new Leaf("分支CompositeX生出的叶子LeafXA"));
comp.Add(new Leaf("分支CompositeX生出的叶子LeafXB"));
root.Add(comp);
Composite comp2 = new Composite("分支CompositeX生出的分支CompositeXY");
comp2.Add(new Leaf("分支CompositeXY生出叶子LeafXYA"));
comp2.Add(new Leaf("分支CompositeXY生出叶子LeafXYB"));
comp.Add(comp2);
root.Add(new Leaf("根节点生成的叶子LeafC"));
Leaf leafD = new Leaf("leaf D");
root.Add(leafD);
root.Remove(leafD);
root.Diaplay(1);
Console.Read();
}
3、程序运行结果
1、场景
假设公司组织结构为:
--总结理
----技术部门经理
------开发人员A
------开发人员B
----销售部门经理
总经理直接领导技术部经理和销售部经理,技术部经理直接领导开发人员A和开发人员B。销售部经理暂时没有直接下属员工,随着公司规模增大,销售部门会新增销售员工。计算组织结构的总工资状况。
如下图所示
IComponent接口:此接口包括了Component和Composite的所有属性,公司每个角 {MOD}都有职称Title和工资待遇Salary,Add方法把员工加入到组织团队中。
Component叶子节点:叶节点没有子节点,Add方法实现没有任何意义。
Composite组合类:此类有一个员工集合_listEmployees,Add方法向此集合中添加员工信息。
GetCost方法获得组织结构中的工资待遇总和
2、代码
1、接口IComponent
- public interface IComponent
- {
- string Title { get; set; }
- decimal Salary { get; set; }
- void Add(IComponent c);
- void GetCost(ref decimal salary);
- }
8.
2、叶节点Component
- public class Component : IComponent
- {
- public string Title { get; set; }
- public decimal Salary { get; set; }
-
- public Component(string Title, decimal Salary)
- {
- this.Title = Title;
- this.Salary = Salary;
- }
-
- public void Add(IComponent c)
- {
- Console.WriteLine("Cannot add to the leaf!");
- }
-
- public void GetCost(ref decimal salary)
- {
- salary += Salary;
- }
- }
22.
3、组合类Composite
1. public class Composite : IComponent
2. {
3. private List _listEmployees;
4.
5. public string Title { get; set; }
6. public decimal Salary { get; set; }
7.
8. public Composite(string Title, decimal Salary)
9. {
10. this.Title = Title;
11. this.Salary = Salary;
12. _listEmployees = new List();
13. }
14.
15. public void Add(IComponent comp)
16. {
17. _listEmployees.Add(comp);
18. }
19.
20. public void GetCost(ref decimal salary)
21. {
22. salary += this.Salary;
23.
24. foreach (IComponent component in this._listEmployees)
25. {
26. component.GetCost(ref salary);
27. }
28. }
29. }
4、客户端代码
- static void Main(string[] args)
- {
- decimal costCEO = 0.0M;
- decimal costVPD = 0.0M;
-
- //Create CEO Node
- IComponent compCEO = new Composite("CEO", 500000);
-
- //Create VP-Development and Developer nodes
- IComponent compVPDev = new Composite("VP-Development", 250000);
-
- IComponent compDev1 = new Component("Developer1", 75000);
- IComponent compDev2 = new Component("Developer2", 50000);
-
- compVPDev.Add(compDev1);
- compVPDev.Add(compDev2);
-
- //Create VP-Sales node
- IComponent compVPSales = new Component("VP-Sales", 300000);
-
- compCEO.Add(compVPDev);
- compCEO.Add(compVPSales);
-
- //Get the cost incurred at the CEO level
- compCEO.GetCost(ref costCEO);
-
- Console.WriteLine(String.Format("The Cost incurred at the CEO level is {0:c} ", costCEO));
-
- //Get the cost incurred at the VP-Development level
- compVPDev.GetCost(ref costVPD);
- Console.WriteLine(String.Format("The Cost incurred at the VP-Development level is {0:c} ", costVPD));
- }
33.
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。解决整合与部分可以被一致对待问题