結構型模式
- 適配器模式(Adapter Pattern)
- 橋接模式(Bridge Pattern)
- 組合模式(Composite Pattern)
- 裝飾器模式(Decorator Pattern)
- 外觀模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
組合模式(Composite Pattern) 是一種結構型設計模式,旨在將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得客戶端可以統一對待單個對象和對象集合,即把對象當作單一對象來處理,從而簡化了操作和使用的復雜性。
核心思想:
組合模式將對象組合成樹形結構,并允許客戶端通過統一的接口對待單一對象和對象組合。其本質是樹形結構中的每個節點可能是單個對象,也可能是對象的組合(集合)。客戶端通過同一接口處理這些對象,從而達到簡化代碼和增強靈活性的目的。
主要角色:
- Component(組件):定義了一個接口,聲明了基本的操作(如?
add()
、remove()
、getChild()
?等),這使得單個對象和組合對象(即樹枝)都能使用相同的操作。 - Leaf(葉子節點):表示樹的葉子節點(即最基本的對象),沒有子節點,實現了組件接口。
- Composite(組合節點):表示樹的枝節點(即含有子節點的對象),實現了組件接口,并且能管理子組件。組合節點可以添加、刪除和獲取子組件。
示例:公司組織結構
假設我們有一個公司組織結構,其中有員工(葉子節點)和經理(組合節點),經理可以有下屬員工或者其他經理。這種組織結構非常適合使用組合模式來實現。
// 組件接口
public interface Employee {void showDetails(); // 顯示員工信息
}// 葉子節點,代表普通員工
public class RegularEmployee implements Employee {private String name;private String position;public RegularEmployee(String name, String position) {this.name = name;this.position = position;}@Overridepublic void showDetails() {System.out.println("姓名: " + name + ", 職位: " + position);}
}import java.util.ArrayList;
import java.util.List;// 組合節點,代表經理(可以包含員工或其他經理)
public class Manager implements Employee {private String name;private String position;private List<Employee> subordinates; // 下屬public Manager(String name, String position) {this.name = name;this.position = position;subordinates = new ArrayList<>();}public void addSubordinate(Employee employee) {subordinates.add(employee);}public void removeSubordinate(Employee employee) {subordinates.remove(employee);}@Overridepublic void showDetails() {System.out.println("姓名: " + name + ", 職位: " + position);System.out.println("下屬: ");for (Employee e : subordinates) {e.showDetails(); // 遞歸調用}}
}public class Client {public static void main(String[] args) {// 創建葉子節點(普通員工)Employee employee1 = new RegularEmployee("張三", "開發工程師");Employee employee2 = new RegularEmployee("李四", "設計師");// 創建組合節點(經理)Manager manager1 = new Manager("王五", "經理");Manager manager2 = new Manager("趙六", "高級經理");// 經理1有下屬員工manager1.addSubordinate(employee1);manager1.addSubordinate(employee2);// 經理2有經理1作為下屬manager2.addSubordinate(manager1);// 展示組織結構System.out.println("經理2的詳細信息:");manager2.showDetails();}
}
解釋:
- Employee(組件):定義了一個接口,所有的員工都實現了這個接口,不管是普通員工還是經理。
- RegularEmployee(葉子節點):普通員工,不能有下屬,實現了?
Employee
?接口。 - Manager(組合節點):經理有下屬員工或者其他經理。它也實現了?
Employee
?接口,并且能夠管理其他員工(包括普通員工和經理)。
在客戶端代碼中,Manager
和 RegularEmployee
都通過 Employee
接口處理,使用 showDetails()
方法遞歸地展示組織結構。無論是單一的普通員工,還是一個包含多個員工和經理的復雜結構,客戶端都可以使用相同的接口來處理它們。
裝飾器模式 vs 組合模式:
- 裝飾器模式:用來動態地向一個對象添加額外的功能,通常涉及一個對象及其裝飾器對象的組合。
- 組合模式:用來將對象組織成樹形結構,表示“部分-整體”的關系,使得客戶端可以統一對待單個對象和對象組合。
優缺點:
優點:
- 透明性:客戶端不需要關心對象的組成細節,所有對象(包括單一對象和組合對象)都通過相同的接口進行操作。
- 靈活性:通過遞歸組合,可以構建出復雜的樹形結構,同時提供統一的操作方法。
- 簡化代碼:對于復雜的層級結構,客戶端不需要針對每一層次編寫單獨的處理代碼,減少了重復代碼。
缺點:
- 過度設計:如果對象本身沒有復雜的層次結構,使用組合模式可能會顯得過于復雜。
- 維護困難:在某些場景下,組合模式可能導致代碼結構變得非常復雜,特別是當組合對象的層次較深時。
總結:
組合模式通過遞歸組合的方式,將對象和對象組合統一處理,使得在處理“部分-整體”結構時,客戶端代碼更加簡潔。它適用于具有樹形結構的場景,如文件系統、組織結構、菜單結構等。