組合模式又稱合成模式,國外設計模式大師GOF把合成模式定義為:“將對象組合成樹形結構以表示” 部分-整體的 層次結構
“將對象組合成樹形結構以表示” 部分-整體的 層次結構可以理解為“通過樹形結構,同等顯示多個獨立的對象以及他們復合而成的合成對象”
1.結構

Component:為組合中的對象聲明接口。在適當的情況下,嘻嘻所有類共有接口的缺省行為,聲明一個接口用戶訪問和管理Component的只組件。在遞歸結構中定義一個接口(可選),用戶訪問一個父部件並在合適的情況下實現它
Leaf:在組合中表示葉借點對象,葉子點沒有子節點對,在組合定義圖元對的行為
CompZ喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc2l0ZTq2qNLl09DX07K/vP61xMTH0Kmyv7z+tcTQ0M6qLLTmtKLX07K/vP4s1NpDb21wb25lbnS907/a1tDKtc/W0+vX07K/vP7T0LnYtcSy2df3PC9wPgo8cD5DbGllbnQ6zai5/UNvbXBvbmVudL3Tv9qy2dfd1+m6z7K/vP61xLbUz/M8L3A+CjxwPjxzdHJvbmc+Mi7KtcD9PC9zdHJvbmc+PC9wPgo8cD48aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20150212/20150212085947166.png" alt="\">
人事管理系統是Componet
員工原理包括 員工列表、新增員工、修改員工、員工資料上傳、員工查詢 子菜單(即沒有內部樹結構),因此,它只是一種樹葉節點(即leaf)
以上樹節點和樹葉根據相同的地位共同組合人事管理系統,這就是組合模式在實際軟件開發中的一個現實案例
應用優勢與時機
組合具備以下一些優勢
1.樹型結構抑郁增加組合對象
2.無論分層對象是否復雜,均可清晰定義,並且可方便的添加新的構件
3.客戶端可簡便的共同調用組合或單個對象
應用場景
當開發樹形結構系統時
當客戶要求軟件需要展現全局與個體關系時
當系統需要共同使用組合結構的全體對象時
示例

package model.composite;
/*
* 排級單位抽象類
* 定義一個軍隊排級單位的抽象類-即Component
*/
public abstract class Group {
private String name = "";//姓名
private String post = "";//官職
private String no = "";//編號
private Group parent = null;
//實際軟件項目中構造函數的定義
public Group(String name, String post, String no) {
super();
this.name = name;
this.post = post;
this.no = no;
}
//獲取軍官信息
public String getMessage(){
String message ="";
message ="姓名:"+this.name;
message = message + "\t官職:"+this.post;
message = message + "\t編號:"+this.no;
return message;
}
//獲取父節點
public Group getParent() {
return parent;
}
//設置父節點
public void setParent(Group parent) {
this.parent = parent;
}
}
package model.composite;
/*
* 葉子類
* 班長-無下屬軍官的軍官-Leaf
*/
public class Monitor extends Group{
public Monitor(String name, String post, String no) {
super(name, post, no);
}
}
package model.composite;
import java.util.ArrayList;
/*
* 節點類
*/
public class Node extends Group {
//構造函數的定義
public Node(String name, String post, String no) {
super(name, post, no);
}
//上機軍官下屬包括哪些下級軍官和下下級軍官
ArrayList juniorList = new ArrayList();
//增加一個下屬,可能是下級軍官,也可能是個下下級軍官
public void addJunior(Group group){
group.setParent(this);
juniorList.add(group);
}
//上級擁有的下屬
public ArrayList getJunior(){
return this.juniorList;
}
}
package model.composite;
import java.util.ArrayList;
/*
* 客戶端測試類
* 展現屬樹型結構:
* 一級節點是排長platoonOfficer ,二級節點是副排長platoonSergeant,三級節點是班長monitor
*/
public class ClientCase {
/*
* 實現樹型結構
*/
public static Node CompositeNodeTree(){
//一級節點
Node node = new Node("傑克", "排長", "A0001");
//二級節點:二個副排長
Node platoonSergeant1 = new Node("李東", "副排長", "A0002");
Node platoonSergeant2 = new Node("將飛", "副排長", "A0003");
//三級節點:班長
Monitor a0002_1 = new Monitor("陳小小", "班長", "A0002_1");
Monitor a0002_2 = new Monitor("李梅", "班長", "A0002_2");
Monitor a0002_3 = new Monitor("師徒青雲", "班長", "A0002_3");
Monitor a0003_1 = new Monitor("金宏", "班長", "A0003_1");
Monitor a0003_2 = new Monitor("馬曉宇", "班長", "A0003_2");
Monitor a0003_3 = new Monitor("林東橋", "班長", "A0003_3");
//設置下級-----------------
//排長下屬二個副排長
node.addJunior(platoonSergeant1);
node.addJunior(platoonSergeant2);
//兩個副排長下的下屬
platoonSergeant1.addJunior(a0002_1);
platoonSergeant1.addJunior(a0002_2);
platoonSergeant1.addJunior(a0002_3);
platoonSergeant2.addJunior(a0003_1);
platoonSergeant2.addJunior(a0003_2);
platoonSergeant2.addJunior(a0003_3);
return node;
}
/*
*使用遞歸的方式通過根節點,遍歷出所有的節點
*/
public static String getTreeMessage(Node node){
ArrayList juniorList = node.juniorList;
String message = "";
for (Group group : juniorList) {
if(group instanceof Monitor){
message = message + group.getMessage()+"\n";
}else{
message = message + group.getMessage() + "\n" +getTreeMessage((Node)group);
}
}
return message;
}
//打印顯示信息
public static void main(String[] args) {
Node node = CompositeNodeTree();
//一級節點-排長
System.out.println(node.getMessage());
//所有軍官信息
System.out.println(getTreeMessage(node));
}
}