組合模式(Composite) 定義 組合模式(Composite),將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。 組合模式有兩種形式:透明方式的組合模式和安全方式的組合模式。 類圖 描述 Component:它可以是介面或抽象類,為葉子 ...
組合模式(Composite)
定義
組合模式(Composite),將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
組合模式有兩種形式:透明方式的組合模式和安全方式的組合模式。
類圖
描述
Component:它可以是介面或抽象類,為葉子和容器對象聲明介面,在該角色中可以包含所有子類共有行為的聲明和實現。在抽象類中定義了訪問及管理它的子類的方法,如增加子對象、刪除子對象、獲取子對象等;
Leaf:表示葉子節點對象,葉子節點沒有子節點,它實現了在抽象類中定義的行為。對於那些訪問及管理子類的方法,可以通過異常等方式進行處理,即在葉子對象中實現子類管理和訪問方法時需要提供異常處理或錯誤提示;
Composite:表示容器節點對象,容器節點包含子節點,其子節點可以是葉子節點,也可以是容器節點,它提供一個集合用於存儲子節點,實現了在抽象類中定義的行為,包括那些訪問及管理子類的方法,在其業務方法中可以遞歸調用其子節點的業務方法。
應用場景
樹枝有多個葉子和子樹枝組成,而子樹枝又可以包含多個葉子和子樹枝;葉子沒有子葉子和子樹枝。
一、透明方式的組合模式
類圖
描述
透明組合模式中,在抽象類Component中聲明瞭所有用於管理成員對象的方法,如Add()、Remove()以及GetChild()等方法,這樣做的好處是確保所有的構件類都有相同的介面。在客戶端看來,葉子對象與容器對象所提供的方法是一致的,客戶端可以相同地對待所有的對象。
/// <summary> /// 葉子和樹枝的聲明介面 /// </summary> public abstract class Component { private string name; /// <summary> /// 節點名稱 /// </summary> public string Name { get { return name; } } private int depth; /// <summary> /// 節點深度 /// </summary> public int Depth { get { return depth; } } public Component(string name, int depth) { this.name = name; this.depth = depth; } #region 管理成員對象的方法 /// <summary> /// 添加子節點 /// </summary> /// <param name="component"></param> public abstract void Add(Component component); /// <summary> /// 移除子節點 /// </summary> /// <param name="component"></param> public abstract void Remove(Component component); /// <summary> /// 獲取子節點 /// </summary> /// <param name="i"></param> /// <returns></returns> public abstract Component GetChild(int i); #endregion /// <summary> /// 子節點操作 /// </summary> public abstract void Display(Component component); } /// <summary> /// 樹枝類 /// </summary> public class Composite : Component { /// <summary> /// 子節點集合 /// </summary> private List<Component> children = new List<Component>(); public Composite(string name, int depth) : base(name, depth) { } public override void Add(Component component) { this.children.Add(component); } public override void Remove(Component component) { this.children.Remove(component); } public override Component GetChild(int i) { if (i >= 0 && i < this.children.Count) { return this.children[i]; } else { return null; } } public override void Display(Component component) { foreach (Component c in ((Composite)component).children) { if (c is Composite) { Console.WriteLine(c.Name.PadLeft(c.Depth + c.Name.Length, '-')); Display(c); } else { c.Display(c); } } } } /// <summary> /// 樹葉類 /// </summary> public class Leaf : Component { public Leaf(string name, int depth) : base(name, depth) { } public override void Add(Component component) { throw new System.NotImplementedException(); } public override void Remove(Component component) { throw new System.NotImplementedException(); } public override Component GetChild(int i) { throw new System.NotImplementedException(); } public override void Display(Component component) { Console.WriteLine(component.Name.PadLeft(component.Depth + component.Name.Length, '-')); } }
二、安全方式的組合模式
類圖
描述
安全組合模式中,在抽象類Component中沒有聲明任何用於管理成員對象的方法,而是在Composite類中聲明並實現這些方法。這種做法是安全的,因為根本不向葉子對象提供這些管理成員對象的方法,對於葉子對象,客戶端不可能調用到這些方法.
/// <summary> /// 葉子和樹枝的聲明介面 /// </summary> public abstract class Component { private string name; /// <summary> /// 節點名稱 /// </summary> public string Name { get { return name; } } private int depth; /// <summary> /// 節點深度 /// </summary> public int Depth { get { return depth; } } public Component(string name, int depth) { this.name = name; this.depth = depth; } /// <summary> /// 子節點操作 /// </summary> public abstract void Display(Component component); } /// <summary> /// 樹枝類 /// </summary> public class Composite : Component { /// <summary> /// 子節點集合 /// </summary> private List<Component> children = new List<Component>(); public Composite(string name, int depth) : base(name, depth) { } #region 管理成員對象的方法 /// <summary> /// 添加子節點 /// </summary> /// <param name="component"></param> public void Add(Component component) { this.children.Add(component); } /// <summary> /// 移除子節點 /// </summary> /// <param name="component"></param> public void Remove(Component component) { this.children.Remove(component); } /// <summary> /// 獲取子節點 /// </summary> /// <param name="i"></param> /// <returns></returns> public Component GetChild(int i) { if (i >= 0 && i < this.children.Count) { return this.children[i]; } else { return null; } } #endregion public override void Display(Component component) { foreach (Component c in ((Composite)component).children) { if (c is Composite) { Console.WriteLine(c.Name.PadLeft(c.Depth + c.Name.Length, '-')); Display(c); } else { c.Display(c); } } } } /// <summary> /// 樹葉類 /// </summary> public class Leaf : Component { public Leaf(string name, int depth) : base(name, depth) { } public override void Display(Component component) { Console.WriteLine(component.Name.PadLeft(component.Depth + component.Name.Length, '-')); } }
透明和安全方式組合模式的區別在於是否在抽象類Component中定義子對象的管理行為。