- 又稱為部分整體模式,是用于把一組相似的對象當(dāng)作一個單一的對象梯刚。組合模式依據(jù)樹形結(jié)構(gòu)來組合對象凉馆,用來表示部分以及整體層次。
結(jié)構(gòu)
- 抽象根節(jié)點(Component):定義系統(tǒng)各個層次對象的共有方法和屬性亡资,可以預(yù)先定義一些默認(rèn)行為和屬性澜共;
- 樹枝節(jié)點(Composite):定義樹枝節(jié)點的行為,存儲子節(jié)點锥腻,組合樹枝節(jié)點和葉子節(jié)點形成一個樹形結(jié)構(gòu)咳胃;
- 葉子節(jié)點(Leaf):葉子節(jié)點對象,其下再無分支旷太,是系統(tǒng)層次的最小單位
實例
-
按照如圖展懈,構(gòu)建菜單管理
// 抽象根節(jié)點
// MenuComponent .java
public abstract class MenuComponent {
// 菜單組件的名稱
protected String name;
// 菜單組件的層級
protected int level;
// 添加子菜單
public void add(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
// 移除子菜單
public void remove(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
// 獲取指定的子菜單
public MenuComponent getChild(int index){
throw new UnsupportedOperationException();
}
// 獲取菜單或者菜單項的名稱
public String getName(){
return name;
}
// 打印菜單名稱的方法(包含子菜單和子菜單項)
public abstract void print();
}
// 樹枝節(jié)點
// Menu.java
public class Menu extends MenuComponent{
// 菜單可以有多個子菜單或者子菜單項
private List<MenuComponent> menuComponentList = new ArrayList<>();
public Menu(String name,int level){
this.name = name;
this.level = level;
}
@Override
public void add(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}
@Override
public void remove(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}
@Override
public MenuComponent getChild(int index) {
return menuComponentList.get(index);
}
@Override
public void print() {
// 打印菜單名稱
for (int i = 0; i < level; i++) {
System.out.print("--");
}
System.out.println(name);
// 打印子菜單或者子菜單像
for(MenuComponent component:menuComponentList){
component.print();
}
}
}
// 葉子節(jié)點
// MenuItem.java
public class MenuItem extends MenuComponent{
public MenuItem(String name,int level){
this.name = name;
this.level = level;
}
@Override
public void print() {
for (int i = 0; i < level; i++) {
System.out.print("--");
}
// 打印菜單項的名稱
System.out.println(name);
}
}
組合模式的分類
透明組合模式
- 在透明組合模式中,抽象根節(jié)點角色中聲明了所有用于管理對象成員的方法供璧。這樣做的好處是確保所有的構(gòu)件都有相同的接口存崖。
- 缺點是不夠安全,因此對于葉子對象和容器對象本質(zhì)上是有區(qū)別的睡毒,葉子對象不可能有下一個層次對象来惧,即不可能包含成員對象,因此對于上例中的add()和remove()等方法是沒有必要的演顾,在編譯階段不會出錯供搀,但是在運行階段,如果調(diào)用這些方法就會出錯钠至。
安全組合模式
- 在安全組合模式中葛虐,在構(gòu)件角色中沒有聲明任何關(guān)于管理成員對象的方法,而是在其子類Menu中聲明這些方法棉钧。缺點是不夠透明屿脐。