一、組合模式簡介(Brief Introduction)
組合模式,將對象組合成樹形結構以表示“部分-整體”的層次結構,組合模式使得用戶 對單個對象和組合對象的使用具有一致性。
二、解決的問題(What To Solve)
解決整合與部分可以被一致對待問題。
三、組合模式分析(Analysis)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<Component> children;
public Composite(string name)
:base(name)
{
if (children == null)
{
children = new List<Component>();
}
}
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、程序運行結果
四.案例分析(Example)
1、場景
假設公司組織結構為:
--總結理
----技術部門經理
------開發人員A
------開發人員B
----銷售部門經理
總經理直接領導技術部經理和銷售部經理,技術部經理直接領導開發人員A和開發人員B。 銷售部經理暫時沒有直接下屬員工,隨著公司規模增大,銷售部門會新增銷售員工。計算組 織結構的總工資狀況。
如下圖所示
IComponent接口:此接口包括了Component和Composite的所有屬性,公司每個角色都有職 稱Title和工資待遇Salary,Add方法把員工加入到組織團隊中。
Component葉子節點:葉節點沒有子節點,Add方法實現沒有任何意義。
Composite組合類:此類有一個員工集合_listEmployees,Add方法向此集合中添加員工信 息。
GetCost方法獲得組織結構中的工資待遇總和
2、代碼
1、接口IComponent
1. public interface IComponent
2. {
3. string Title { get; set; }
4. decimal Salary { get; set; }
5. void Add(IComponent c);
6. void GetCost(ref decimal salary);
7. }
2、葉節點Component
1. public class Component : IComponent
2. {
3. public string Title { get; set; }
4. public decimal Salary { get; set; }
5.
6. public Component(string Title, decimal Salary)
7. {
8. this.Title = Title;
9. this.Salary = Salary;
10. }
11.
12. public void Add(IComponent c)
13. {
14. Console.WriteLine("Cannot add to the leaf!");
15. }
16.
17. public void GetCost(ref decimal salary)
18. {
19. salary += Salary;
20. }
21. }
3、組合類Composite
1. public class Composite : IComponent
2. {
3. private List<IComponent> _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<IComponent>();
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、客戶端代碼
1. static void Main(string[] args)
2. {
3. decimal costCEO = 0.0M;
4. decimal costVPD = 0.0M;
5.
6. //Create CEO Node
7. IComponent compCEO = new Composite("CEO", 500000);
8.
9. //Create VP-Development and Developer nodes
10. IComponent compVPDev = new Composite("VP-Development", 250000);
11.
12. IComponent compDev1 = new Component("Developer1", 75000);
13. IComponent compDev2 = new Component("Developer2", 50000);
14.
15. compVPDev.Add(compDev1);
16. compVPDev.Add(compDev2);
17.
18. //Create VP-Sales node
19. IComponent compVPSales = new Component("VP-Sales", 300000);
20.
21. compCEO.Add(compVPDev);
22. compCEO.Add (compVPSales);
23.
24. //Get the cost incurred at the CEO level
25. compCEO.GetCost(ref costCEO);
26.
27. Console.WriteLine(String.Format ("The Cost incurred at the CEO level is {0:c} ", costCEO));
28.
29. //Get the cost incurred at the VP-Development level
30. compVPDev.GetCost (ref costVPD);
31. Console.WriteLine(String.Format ("The Cost incurred at the VP-Development level is {0:c} ", costVPD));
32. }
五、總結(Summary)
組合模式,將對象組合成樹形結構以表示“部分-整體”的層次結構,組合模式使得用戶 對單個對象和組合對象的使用具有一致性。解決整合與部分可以被一致對待問題。
出處:http://www.cnblogs.com/ywqu