目錄 7、組合模式 7.1 組合模式(Composite) 7.2 叉樹結構 7.3 文件系統 7.4 目錄樹展示 7.5 自相似性的涌現 7.6 組合模式的各角色定義 7.7 組合
7、組合模式
7.1 組合模式(Composite)
是針對由多個節點對象(部分)組成的樹形結構 的對象(整體)而發展出的一種結構型設計模式 它能夠使客戶端在操作整體對象 或者其下的每個節點對象 時做出統一的響應 ,保證樹形結構對象使用方法的一致性 整體和部分,有類似結構 測試類結構
7.2 叉樹結構
某些具有從屬關系的事物 之間存在著一定的相似性 不管從哪個層級,我們都會得到一個固定的結構 這種結構類似于經典的“叉樹”結構:無論數據元素是“根”“枝”,還是“葉”,甚至是整體的樹,都具有類似的結構 我們可以用組合模式來表達“部分/整體”的層次結構 ,提取并抽象其相同的部分 ,特殊化其不同的部分 ,以提高系統的可復用性與可擴展性
7.3 文件系統
以類似于樹結構的文件系統的目錄結構為例 抽象節點類Node 定義一個抽象的“節點”類來模糊“文件夾”與“文件” 構造方法中接收并初始化已定義的節點名 ,否則不允許節點被創建,這也是可以固化下來的邏輯 。聲明抽象方法,模糊行為并留給子類去實現
package composite ;
public abstract class Node { protected String name; public Node ( String name) { this . name = name; } protected abstract void add ( Node child) throws Exception ;
}
節點實現類1:文件夾類Folder 文件夾類繼承了抽象節點類Node 文件夾下級可以包含任意多個文件夾或者文件:次級節點列表List
package composite ; import java. util. ArrayList ;
import java. util. List ;
public class Folder extends Node { List < Node > children = new ArrayList < > ( ) ; public Folder ( String name) { super ( name) ; } @Override protected void add ( Node child) { children. add ( child) ; }
}
package composite ;
public class File extends Node { public File ( String name) { super ( name) ; } @Override protected void add ( Node child) { System . out. println ( "文件類型不能添加子節點" ) ; }
}
package composite ;
public class Client { public static void main ( String [ ] args) throws Exception { Node driveD = new Folder ( "測試盤" ) ; Node doc = new Folder ( "文檔" ) ; doc. add ( new File ( "簡歷.doc" ) ) ; doc. add ( new File ( "項目介紹.ppt" ) ) ; driveD. add ( doc) ; Node music = new Folder ( "音樂" ) ; Node jay = new Folder ( "周杰倫" ) ; jay. add ( new File ( "雙截棍.mp3" ) ) ; jay. add ( new File ( "告白氣球.mp3" ) ) ; jay. add ( new File ( "聽媽媽的話.mp3" ) ) ; Node jack = new Folder ( "張學友" ) ; jack. add ( new File ( "吻別.mp3" ) ) ; jack. add ( new File ( "一千個傷心的理由.mp3" ) ) ; music. add ( jay) ; music. add ( jack) ; driveD. add ( music) ; }
}
7.4 目錄樹展示
要體現出組合模式的優勢還在于如何運用這個樹結構 分級展示整棵目錄樹 輸出節點名稱(文件夾名/文件名)之前加上數個空格以表示不同層級 修改抽象節點類Node并加入展示方法tree() protected void tree ( int space) { for ( int i = 0 ; i < space; i++ ) { System . out. print ( " " ) ; } System . out. println ( name) ; } protected void tree ( ) { this . tree ( 0 ) ; }
節點實現類File和Folder重寫展示方法,Folder還要展示其子級 @Override public void tree ( int space) { super . tree ( space) ; space++ ; for ( Node child : children) { child. tree ( space) ; } }
@Override
public void tree ( int space) { super . tree ( space) ;
}
客戶端在任何一級節點上只要調用其展示方法并傳入當前目錄所需的空格偏移量,就可出現樹形列表了 driveD. tree ( ) ;
空格偏移量這個必傳參數,可以為抽象節點類添加一個無參的展示方法,默認為0
7.5 自相似性的涌現
組合模式將樹形結構的特點發揮得淋漓盡致 作為最高層級抽象的抽象節點類 (接口)泛化了所有節點類 ,使任何“整體”或“部分”達成統一 枝(根)節點與葉節點的多態化實現以及組合關系進一步勾勒出的樹形結構
7.6 組合模式的各角色定義
Component(組件接口): 所有復合節點與葉節點的高層抽象 ,定義出需要對組件操作的接口標準 如抽象節點類Node,具體使用接口還是抽象類需根據具體場景而定。 Composite(復合組件): 包含多個子組件對象(可以是復合組件或葉端組件)的復合型組件,并實現組件接口中定義的操作方法。 如:“根節點/枝節點”的文件夾類Folder Leaf(葉端組件): 不包含子組件的終端組件,同樣實現組件接口中定義的操作方法。 如: “葉節點”的文件類File Client(客戶端): 按所需的層級關系部署相關對象并操作組件接口所定義的接口,即可遍歷樹結構上的所有組件
7.7 組合
類似的結構總是在重復、迭代地顯現出某種自似性 其部分與整體一致的呈現與“組合模式”如出一轍