把A和B組合在一起看成一個對象
需求中是體現部分與整體層次的結構時,以及希望用戶可以忽略組合對象與單個對象的不同,統一的使用組合
結構中的所有對象時,就應該考慮用組合模式了。 ————摘自《大話設計模式》
基本結構如下:
①、抽象接口
抽象方法:添加對象
抽象方法:移除對象
抽象方法方法A(用於子類覆寫後,處理具體事務)
②、具體葉節點類,繼承自抽象接口(無擴展)
覆寫抽象方法,但由於葉節點無需擴展,所以覆寫後不做任何處理
覆寫方法A
③、具體枝節點類,繼承自抽象接口(可擴展)
屬性:一個集合,用於置放抽象接口的實現
覆寫“添加對象”的抽象方法
覆寫“移除對象”的抽象方法
覆寫方法A,除去自身的個性實現外,還會遍歷集合,爲下級提供特殊實現
④、調用者
準備好各種組件,區分各個組件的職能(根、枝、葉)並進行組合,組裝成樹
示例代碼: 以公司的組織結構展示爲例
①、抽象接口#########################################
/**
* 抽象公司
*/
public abstract class Company {
protected String name; //公司名稱
public Company(String name){
this.name = name;
};
public abstract void add(Company c); //增加公司
public abstract void remove(Company c); //去除公司
public abstract void display(int depth); //展示
}
②、具體葉節點#########################################
/**
* 公司部門(葉節點無需擴展)
*/
public class Department extends Company {
public Department(String name) {
super(name);
}
@Override
public void display(int depth) { //展示方法
int i = 0;
while(i<depth){
System.out.print("-");
i++;
}
System.out.print(name+"\n");
}
@Override
public void add(Company c) {} //由於葉節點無需擴展,所以爲空實現
@Override
public void remove(Company c) {} //由於葉節點無需擴展,所以爲空實現
}
③、具體枝節點#########################################
/**
* 公司,(枝節點可擴展 )
*/
public class ConcreteCompany extends Company{
private List<Company> compList = new ArrayList<Company>(); //下屬公司集合
public ConcreteCompany(String name) {
super(name);
}
@Override
public void display(int depth) {//展示方法
int i = 0;
while(i<depth){
System.out.print("-");
i++;
}
System.out.print(name+"\n");
for(Company c:compList){ //下級公司展示
c.display(depth+2);
}
}
@Override
public void add(Company c) { //添加下級公司
compList.add(c);
}
@Override
public void remove(Company c) { //移除下級公司
compList.remove(c);
}
}
④、調用者#########################################
public class Test {
public static void main(String[] args) throws Exception {
Company root = new ConcreteCompany("北京總公司");
root.add(new Department("北京總公司人事部"));
Company comp = new ConcreteCompany("河北分公司");
comp.add(new Department("河北分公司財務部"));
Company comp1 = new ConcreteCompany("張家口辦事處");
comp1.add(new Department("張家口辦事處人事部"));
Company comp2 = new ConcreteCompany("廊坊辦事處");
comp2.add(new Department("廊坊辦事處人事部"));
//以下3行進行結構組裝
root.add(comp);
comp.add(comp1);
comp.add(comp2);
System.out.println("公司結構圖展示:");
root.display(1); //展示
}
}
運行結果:
公司結構圖展示:
-北京總公司
---北京總公司人事部
---河北分公司
-----河北分公司財務部
-----張家口辦事處
-------張家口辦事處人事部
-----廊坊辦事處
-------廊坊辦事處人事部