文章出處

索引

意圖

將對象組合成樹形結構以表示 “部分-整體” 的層次結構。

Composite 使得用戶對于單個對象和組合對象的使用具有一致性。

Compose objects into tree structures to represent part-whole hierarchies.

Composite lets clients treat individual objects and compositions of objects uniformly.

結構

典型的 Composite 對象結構:

參與者

Component

  • 為組合中的對象聲明接口。
  • 在適當的情況下,實現所有類共有接口的缺省行為
  • 聲明一個接口用于訪問和管理 Component 的子組件。
  • 在遞歸結構中定義一個接口,用于訪問一個父部件,并在合適的情況下實現它。

Leaf

  • 在組合中表示葉節點對象,葉節點沒有子節點。
  • 在組合中定義圖元對象的行為。

Composite

  • 定義有子部件的那些部件的行為。
  • 在 Composite 接口中實現與子部件有關的操作。

Client

  • 通過 Component 接口操縱組合部件的對象。

適用性

在以下情況下可以使用 Composite 模式:

  • 你想表示對象的 “部分-整體” 層次結構。
  • 你希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。

缺點

  • 與類層次結構設計原則沖突

Composite 模式的目的之一是使得用戶不知道它們正在使用具體的 Leaf 和 Composite 類。

為達到這一目的,Component 需要為 Leaf 和 Composite 定義一些公共操作,并提供缺省的實現,而 Leaf 和 Composite 子類可以對它們進行重定義。

然而,這個目標會與類層次結構設計原則沖突,該原則規定:一個類只能定義那些對它的子類有意義的操作。

效果

  • 定義了包含基本對象和組合對象的類層次結構。
  • 簡化客戶代碼。
  • 使得更容易增加新類型的組件。
  • 使你的設計變得更加一般化。

相關模式

  • Command 模式描述了如何用一個 MacroCommand Composite 類組成一些 Command 對象,并對它們進行排序。
  • 通常 “部件-父部件” 連接用于 Responsibility of Chain 模式。
  • Decorator 模式經常與 Composite 模式一起使用。它們通常有一個公共的父類。
  • Flyweight 讓你共享組件,但不再能引用它們的父部件。
  • Iterator 可以用來遍歷 Composite。
  • Visitor 將本來應該分布在 Composite 和 Leaf 類中的操作和行為局部化。

實現

實現方式(一):在 Component 中定義公共接口以保持透明性但損失安全性。

在 Component 中定義 Add 和 Remove 操作需要考慮安全性和透明性。

在類層次結構的根部定義子節點管理接口的方法具有良好的透明性,但是這一方法是以安全性為代價的,因為客戶有可能會做一些無意義的事情,例如在 Leaf 中 Add 對象等。

在 Composite 類中定義管理子部件的方法具有良好的安全性,但是這又損失了透明性,因為 Leaf 和 Composite 具有不同的接口。

 1 namespace CompositePattern.Implementation1
 2 {
 3   public abstract class Component
 4   {
 5     protected List<Component> _children = new List<Component>();
 6 
 7     public abstract void Operation();
 8 
 9     public virtual void Add(Component component)
10     {
11       _children.Add(component);
12     }
13 
14     public virtual void Remove(Component component)
15     {
16       _children.Remove(component);
17     }
18 
19     public virtual IEnumerable<Component> GetChildren()
20     {
21       return _children;
22     }
23   }
24 
25   public class Leaf : Component
26   {
27     public override void Operation()
28     {
29       // do something
30     }
31 
32     public override void Add(Component component)
33     {
34       throw new InvalidOperationException();
35     }
36 
37     public override void Remove(Component component)
38     {
39       throw new InvalidOperationException();
40     }
41 
42     public override IEnumerable<Component> GetChildren()
43     {
44       throw new InvalidOperationException();
45     }
46   }
47 
48   public class Composite : Component
49   {
50     public override void Operation()
51     {
52       foreach (var child in _children)
53       {
54         child.Operation();
55       }
56       // may do something
57     }
58   }
59 
60   public class Client
61   {
62     public void TestCase1()
63     {
64       Component component1 = new Leaf();
65       Component component2 = new Composite();
66 
67       component2.Add(component1);
68 
69       component1.Operation();
70       component2.Operation();
71     }
72   }
73 }

設計模式之美》為 Dennis Gao 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()