描述
????組合模式颤难,將對象組合成樹形結構以表示“部分-整體”的層次結構矾麻,組合模式使得用戶對單個對象和組合對象的使用具有一致性提岔。
簡介
????安全模式的組合模式要求管理聚集的方法只出現(xiàn)在樹枝構件類中匪傍,而不出現(xiàn)在樹葉構件類中。
????透明式的組合模式要求所有的具體構件類观挎,不論樹枝構件還是樹葉構件琴儿,均符合一個固定接口。
角色
- 抽象構件(Component)角色:這是一個抽象角色嘁捷,它給參加組合的對象定義出公共的接口及其默認行為造成,可以用來管理所有的子對象。組合對象通常把它所包含的子對象當做類型為Component的對象雄嚣。在安全式的組合模式里晒屎,構件角色并不定義出管理子對象的方法,這一定義由樹枝構件對象給出缓升。
- 樹葉構件(Leaf)角色:樹葉對象是沒有下級子對象的對象鼓鲁,定義出參加組合的原始對象的行為。
- 樹枝構件(Composite)角色:代表參加組合的有下級子對象的對象港谊。樹枝構件類給出所有的管理子對象的方法骇吭,如add()、delete()以及get()封锉。
優(yōu)缺點
優(yōu)點
- 組合模式使得客戶端代碼可以一致地處理對象和對象容器绵跷,無需關系處理的單個對象膘螟,還是組合的對象容器。
- 可以更容易地往組合對象中加入新的構件碾局。
- 將”客戶代碼與復雜的對象容器結構“解耦荆残。
缺點
- 使得設計更加復雜【坏保客戶端需要花更多時間理清類之間的層次關系内斯。
- 在使用組合模式時,其葉子和樹枝的聲明都是實現(xiàn)類像啼,而不是接口俘闯,違反了依賴倒置原則。
使用場景
- 當想表達對象的部分-整體的層次結構時忽冻。(部分真朗、整體場景,如樹形菜單僧诚,文件遮婶、文件夾的管理。)
- 希望用戶忽略組合對象與單個對象的不同湖笨,用戶將統(tǒng)一地使用組合結構中的所有對象時旗扑。
示例
安全式組合模式
public interface Component {
/**
* 輸出組建自身的名稱
*/
void operation(String name);
}
public class Composite implements Component {
/**
* 組合對象的名字
*/
private String name;
/**
* 用來存儲組合對象中包含的子組件對象
*/
private List<Component> componentList = new ArrayList<>();
/**
* 傳入組合對象的名稱
*
* @param name 組合對象的名稱
*/
public Composite(String name) {
this.name = name;
}
/**
* 聚集管理方法,增加一個子構件對象
*
* @param component 子構件對象
*/
public void addComponent(Component component) {
this.addComponent(component);
}
/**
* 聚集管理方法慈省,返回所有子構件對象
*/
public List<Component> getComponent() {
return componentList;
}
/**
* 輸出對象的自身結構
* @param preStr 前綴臀防,主要是按照層級拼接空格,實現(xiàn)向后縮進
*/
/**
* 聚集管理方法边败,刪除一個子構件對象
*
* @param index 子構件對象的下標
*/
public void removeComponent(int index) {
componentList.remove(index);
}
/**
* 輸出組建自身的名稱
*/
@Override
public void operation(String name) {
System.out.println(this.name);
if (this.componentList != null) {
for (Component c : componentList) {
c.operation(name);
}
}
}
}
public class Leaf implements Component {
private String name;
public Leaf(String name) {
this.name = name;
}
@Override
public void operation(String name) {
System.out.println(name + "-" + this.name);
}
}
public class Client {
public static void main(String[] args) {
Composite root = new Composite("我的電腦");
Composite c1 = new Composite("C盤");
Composite c2 = new Composite("D盤");
Leaf leaf1 = new Leaf("文件1");
Leaf leaf2 = new Leaf("文件2");
Leaf leaf3 = new Leaf("文件3");
Leaf leaf4 = new Leaf("文件4");
root.addComponent(c1);
root.addComponent(c2);
c1.addComponent(leaf1);
c1.addComponent(leaf2);
c2.addComponent(leaf3);
c2.addComponent(leaf4);
root.operation("test");
}
}
透明式組合模式
public abstract class Component {
public abstract void operation(String name);
public void addComponent(Component component) {
throw new UnsupportedOperationException("葉子節(jié)點不支持此功能");
}
public List<Component> getComponent() {
throw new UnsupportedOperationException("葉子節(jié)點不支持此功能");
}
public void removeComponent(int index) {
throw new UnsupportedOperationException("葉子節(jié)點不支持此功能");
}
}
public class Composite extends Component {
/**
* 組合對象的名字
*/
private String name;
/**
* 用來存儲組合對象中包含的子組件對象
*/
private List<Component> componentList = new ArrayList<>();
/**
* 傳入組合對象的名稱
*
* @param name 組合對象的名稱
*/
public Composite(String name) {
this.name = name;
}
/**
* 聚集管理方法袱衷,增加一個子構件對象
*
* @param component 子構件對象
*/
@Override
public void addComponent(Component component) {
this.addComponent(component);
}
/**
* 聚集管理方法,返回所有子構件對象
*/
@Override
public List<Component> getComponent() {
return componentList;
}
/**
* 輸出對象的自身結構
* @param preStr 前綴笑窜,主要是按照層級拼接空格祟昭,實現(xiàn)向后縮進
*/
/**
* 聚集管理方法,刪除一個子構件對象
*
* @param index 子構件對象的下標
*/
@Override
public void removeComponent(int index) {
componentList.remove(index);
}
/**
* 輸出組建自身的名稱
*/
@Override
public void operation(String name) {
System.out.println(this.name);
if (this.componentList != null) {
for (Component c : componentList) {
c.operation(name);
}
}
}
}
public class Leaf extends Component {
private String name;
public Leaf(String name) {
this.name = name;
}
@Override
public void operation(String name) {
System.out.println(name + "-" + this.name);
}
}
public class Client {
public static void main(String[] args) {
Composite root = new Composite("我的電腦");
Composite c1 = new Composite("C盤");
Composite c2 = new Composite("D盤");
Component leaf1 = new Leaf("文件1");
Component leaf2 = new Leaf("文件2");
Component leaf3 = new Leaf("文件3");
Component leaf4 = new Leaf("文件4");
root.addComponent(c1);
root.addComponent(c2);
c1.addComponent(leaf1);
c1.addComponent(leaf2);
c2.addComponent(leaf3);
c2.addComponent(leaf4);
root.operation("test");
}
}