java23種設計模式——八、組合模式
阿新 • • 發佈:2020-08-29
## 目錄
[java23種設計模式—— 一、設計模式介紹](https://www.cnblogs.com/codermy/p/13565137.html)
[java23種設計模式—— 二、單例模式](https://www.cnblogs.com/codermy/p/13566365.html)
[java23種設計模式——三、工廠模式](https://www.cnblogs.com/codermy/p/13569486.html)
[java23種設計模式——四、原型模式](https://www.cnblogs.com/codermy/p/13571750.html)
[java23種設計模式——五、建造者模式](https://www.cnblogs.com/codermy/p/13575590.html)
[java23種設計模式——六、介面卡模式](https://www.cnblogs.com/codermy/p/13577408.html)
[java23種設計模式——七、橋接模式](https://www.cnblogs.com/codermy/p/13580922.html)
[java23種設計模式——八、組合模式](https://www.cnblogs.com/codermy/p/13580924.html)
## 介紹
組合模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的物件當作一個單一的物件。組合模式依據樹形結構來組合物件,用來表示部分以及整體層次。這種型別的設計模式屬於結構型模式,它建立了物件組的樹形結構。
這種模式建立了一個包含自己物件組的類。該類提供了修改相同物件組的方式。
組合模式類似樹形結構,上一層節點的包含多個下一層的節點,而下一層的節點只依附於一個上一層的節點。
## 實現
我們先來看下組合模式的角色。
- Component抽象構建角色,抽象共有的方法和屬性,
- Leaf葉子構件,葉子物件,沒有其他分支,類似於樹葉
- Composite數值構件,組合葉子和其他樹枝組合成一個完整的樹,類似於樹枝
通常大學裡都有很多個系,每個系又包含多個專業,每個專業也有多個班級。
首先有一個抽象學校類,即component角色
```java
/**
* @author codermy
* @createTime 2020/7/28
*/
//學校
public abstract class School {
//展示樹形結構
public abstract void display(String f);
//新增分支
public void add(School branch){
throw new UnsupportedOperationException("不支援此功能");
};
//刪除分支
public void remove(School branch) {
// 若葉子物件沒有這個功能,或子類未實現這個功能
throw new UnsupportedOperationException("不支援此功能");
}
}
```
現在有一個Branch類(即Composite角色)繼承了學校類,並實現其中方法。我們可以把它抽象的想成,學校的分院與專業的結構都一樣,所以新建它們都公用這一個類
```java
/**
* @author codermy
* @createTime 2020/7/28
* 分院
*/
public class Branch extends School {
//學校集合
private List schoolList = new ArrayList<>();
private String name;
public Branch(String name){
this.name=name;
}
@Override
public void display(String f) {
System.out.println(f + name);
// 如果還包含其他子元件,那麼就輸出這些子元件物件
if (null != schoolList) {
// 新增一個空格,表示向後縮排一個空格
f += "---";
// 輸出當前物件的子元件物件
for (School school : schoolList) {
// 遞迴地進行子元件相應方法的呼叫,輸出每個子元件物件
school.display(f);
}
}
}
public void add(School branch){
schoolList.add(branch);
}
public void remove(School branch){
schoolList.remove(branch);
}
}
```
而學校裡最小的單元是班級,新建這個類(即Leaf)
```java
/**
* @author codermy
* @createTime 2020/7/28
*/
public class Class extends School {
private String name;
public Class(String name){
this.name = name;
}
@Override
public void display(String f) {
System.out.println(f + "-"+ name);
}
}
```
client類測試
```java
/**
* @author codermy
* @createTime 2020/7/28
*/
public class Client {
public static void main(String[] args) {
//新建一個學校
School university = new Branch("南京大學");
//新建分院
School branch1 = new Branch("計算機與軟體學院");
School branch2 = new Branch("外國語學院");
//新建專業
School profession1 = new Branch("軟體工程");
School profession2 = new Branch("網路工程");
//新建班級
profession1.add(new Class("軟體1801"));
profession1.add(new Class("軟體1802"));
branch1.add(profession1);
branch1.add(profession2);
university.add(branch1);
university.add(branch2);
university.display("-");
}
}
```
輸出
```bash
-南京大學
----計算機與軟體學院
-------軟體工程
-----------軟體1801
-----------軟體1802
-------網路工程
----外國語學院
```
## 優缺點
**優點:**
- 1、高層模組呼叫簡單。
- 2、節點自由增加。
- 3、可以清楚地定義分層次的複雜物件,表示物件的全部或部分層次,使得增加新構件也更容易。
**缺點:**
- 1、在使用組合模式時,其葉子和樹枝的宣告都是實現類,而不是介面,違反了依賴倒置原則。
- 2、使設計變得更加抽象,物件的業務規則如果很複雜,則實現組合模式具有很大挑