4.3 COMPOSITE(組合) — 對象結構型模式

1 意圖

將對象組合成樹形結構以表示“部分-整體”的層次結構。Composite使得用戶對單個對象和組合對象的使用具有一致性。

2 動機

在繪圖編輯器和圖形捕捉系統(tǒng)這樣的圖形應用程序中,用戶可以使用簡單的組件創(chuàng)建復雜的圖表。用戶可以組合多個簡單組件以形成一些較大的組件,這些組件又可以組合成更大的組件。一個簡單的實現(xiàn)方法是為Text和Line這樣的圖元定義一些類,另外定義一些類作為這些圖元的容器類( Container )。

然而這種方法存在一個問題:使用這些類的代碼必須區(qū)別對待圖元對象與容器對象,而實際上大多數(shù)情況下用戶認為它們是一樣的。對這些類區(qū)別使用,使得程序更加復雜。Composite模式描述了如何使用遞歸組合,使得用戶不必對這些類進行區(qū)別,如下圖所示。


image.png

Composite模式的關鍵是一個抽象類,它既可以代表圖元,又可以代表圖元的容器。在圖形系統(tǒng)中的這個類就是Graphic,它聲明一些與特定圖形對象相關的操作,例如Draw。同時它也聲明了所有的組合對象共享的一些操作,例如一些操作用于訪問和管理它的子部件。

Picture類定義了一個Graphic 對象的聚合。Picture 的Draw操作是通過對它的子部件調用Draw實現(xiàn)的,Picture還用這種方法實現(xiàn)了一些與其子部件相關的操作。由于Picture接口與Graphic接口是一致的,因此Picture對象可以遞歸地組合其他Picture對象。

下圖是一個典型的由遞歸組合的Graphic對象組成的組合對象結構。


image.png
3 適用性

以下情況使用Composite模式:

  • 你想表示對象的部分-整體層次結構
  • 你希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結構中的所有對象
4 結構
image.png

典型的Composite對象結構如下圖所示:


image.png
5 參與者
  • component(Graphic)
    ——為組合中的對象聲明接口
    ——在適當?shù)那闆r下,實現(xiàn)所有類共有接口的缺省行為
    ——聲明一個接口用于訪問和管理Component的子組件
    ——(可選)在遞歸結構中定義一個接口,用于訪問一個父部件,并在合適的情況下實現(xiàn)它。
  • Leaf(Rectangle、Line、Text等)
    ——在組合中表示葉節(jié)點對象,葉節(jié)點沒有子節(jié)點
    ——在組合中定義圖元對象的行為
  • Composite(Picture)
    ——定義有子部件的那些部件的行為
    ——存儲子部件
    ——在Component接口中實現(xiàn)與子部件有關的操作
  • Client
    ——通過Component接口操作組合部件的對象
6 協(xié)作

用戶使用Component類接口與組合結構中的對象進行交互。如果接收者是一個葉節(jié)點,則直接處理請求。如果接受者是Composite,它通常將請求發(fā)送給它的子部件,在轉發(fā)請求之前或之后可能執(zhí)行一些輔助操作。

7 效果
  • 1 定義了包含基本對象和組合對象的類層次結構,基本對象可以被組合成更復雜的組合對象,而這個組合對象又可以被組合;
  • 2 簡化客戶代碼:客戶可以一致地使用組合結構和單個對象;
  • 3 使得更容易增加新類型的組件;
  • 4 使你的設計變得更加一般化。
8 實現(xiàn)

要考慮的問題:

  • 1 顯式的父部件引用:保持從子部件到父部件的引用能簡化組合結構的遍歷和管理;
  • 2 共享組件;
  • 3 最大化Component接口;
  • 4 聲明管理子部件的操作;
  • 5 Component是否應該實現(xiàn)一個Component列表;
  • 6 子部件排序;
  • 7 使用高速緩沖存貯改善性能;
  • 8 應該由誰刪除Component
  • 9 存貯組件最好用哪一種數(shù)據(jù)結構;
9 代碼示例

github地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容