組合模式概念
以下摘自菜鳥教程
意圖:將對象組合成樹形結構以表示”部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
主要解決:它在我們樹型結構的問題中,模糊了簡單元素和複雜元素的概念,客戶程序可以向處理簡單元素一樣來處理複雜元素,從而使得客戶程序與複雜元素的內部結構解耦。
何時使用:
1、您想表示對象的部分-整體層次結構(樹形結構)。
2、您希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。如何解決:樹枝和葉子實現統一接口,樹枝內部組合該接口。
關鍵代碼:樹枝內部組合該接口,並且含有內部屬性 List,裏面放 Component。
應用實例:
1、算術表達式包括操作數、操作符和另一個操作數,其中,另一個操作符也可以是操作數、操作符和另一個操作數。
2、在 JAVA AWT 和 SWING 中,對於 Button 和 Checkbox 是樹葉,Container 是樹枝。優點:
1、高層模塊調用簡單。
2、節點自由增加。缺點:在使用組合模式時,其葉子和樹枝的聲明都是實現類,而不是接口,違反了依賴倒置原則。
使用場景:部分、整體場景,如樹形菜單,文件、文件夾的管理。
注意事項:定義時爲具體類。
組合模式主要突出兩個關鍵字:樹形結構、整體-部分
接下來先看一個案例
案例
已知,電腦中文件與文件夾。父文件夾中可以存在子文件和子文件夾,子文件夾中又可以存在其子文件夾的子文件和子文件夾。
Component(抽象構件)
可以是接口或抽象類,爲葉子構件和容器構件對象聲明接口,在該角色中可以包含所有子類共有行爲的聲明和實現。在抽象構件中定義了訪問及管理它的子構件的方法,如增加子構件、刪除子構件、獲取子構件等。
public interface Component {
/**
* 添加組件
* @return void
* @param component
* 時間:2018年4月27日
*/
void add(Component component);
/**
* 移除組件
* @return void
* @param component
* 時間:2018年4月27日
*/
void remove(Component component);
/**
* 獲取組件
* @return Component
* @param i
* @return
* 時間:2018年4月27日
*/
Component getCom(int i);
/**
* 需要執行的方法
* @return void
* 時間:2018年4月27日
*/
void operation();
}
Leaf(葉子構件)
在組合結構中表示葉子節點對象,葉子節點沒有子節點,它實現了在抽象構件中定義的行爲。對於那些訪問及管理子構件的方法,可以通過異常等方式進行處理。
public class CFile implements Component{
private String name;
public CFile(String name) {
this.name = name;
}
@Override
public void add(Component component) {
System.out.println("error");
}
@Override
public void remove(Component component) {
System.out.println("error");
}
@Override
public Component getCom(int i) {
System.out.println("error");
return null;
}
@Override
public void operation() {
System.out.println(name);
}
}
Composite(容器構件)
在組合結構中表示容器節點對象,容器節點包含子節點,其子節點可以是葉子節點,也可以是容器節點,它提供一個集合用於存儲子節點,實現了在抽象構件中定義的行爲,包括那些訪問及管理子構件的方法,在其業務方法中可以遞歸調用其子節點的業務方法。
public class CFolder implements Component{
private String name;
private List<Component> list;
public CFolder(String name) {
this.name = name;
list = new ArrayList<>();
}
@Override
public void add(Component component) {
list.add(component);
}
@Override
public void remove(Component component) {
list.remove(component);
}
@Override
public Component getCom(int i) {
return list.get(i);
}
@Override
public void operation() {
System.out.println(name);
System.out.println("打開了:" + name);
for (Component component : list) {
component.operation();
}
}
}
測試類
public class Test {
public static void main(String[] args) {
Component component1 = new CFile("A");
Component component2 = new CFile("B");
Component component3 = new CFile("C");
Component component4 = new CFile("D");
Component component5 = new CFolder("1");
Component component6 = new CFolder("2");
Component component7 = new CFolder("3");
component5.add(component1);
component5.add(component2);
component5.add(component6);
component6.add(component3);
component6.add(component7);
component7.add(component4);
component5.operation();
}
}
本文參考