基本介紹
1、組合模式(Composite Pattern)又叫部分整體模式,他創建了物件組的樹形結構,將物件組合成樹狀結構以表示「整體 - 部分」的層次關系,
2、組合模式使得用戶對單個物件和組合物件的訪問具有一致性,即:組合能讓客戶以一致的方式處理個別物件以及組合物件
模式結構
Component(抽象構件):定義參加組合物件的公有方法和屬性,可以定義一些默認的行為和屬性,
Composite(容器構件):樹枝物件,它的作用是組合樹枝結點和葉子結點形成一個樹形結構,
Leaf(葉子構件):葉子構件的下面沒有其他分支,也就是遍歷的最小單位,
組合模式有兩種實作:安全模式和透明模式,其結構如下圖所示
- 安全組合模式:在抽象構件角色中沒有宣告任何用于管理成員物件的方法,而是在容器構件
Composite類中宣告并實作這些方法, - 透明組合模式:抽象構建角色中宣告了所有用于管理成員物件的方法,對其它構件公開透明,

簡單案例
要求:在頁面展示出公司的部門組成(一個公司有多個部門,每個部門有多個小組);
這是一種很明顯的樹形結構,因此可以用組合模式解決
「抽象構件」:OrganizationComponent
public abstract class OrganizationComponent {
private String name;
public OrganizationComponent(String name) {
this.name = name;
}
protected void add(OrganizationComponent component) {
throw new UnsupportedOperationException("不支持添加操作");
}
protected void remove(OrganizationComponent component) {
throw new UnsupportedOperationException("不支持洗掉操作");
}
protected abstract void print();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
「容器構件」:Company、Department
public class Company extends OrganizationComponent {
private List<OrganizationComponent> components = new ArrayList<>();
public Company(String name) {
super(name);
}
@Override
protected void add(OrganizationComponent component) {
components.add(component);
}
@Override
protected void remove(OrganizationComponent component) {
components.remove(component);
}
@Override
protected void print() {
System.out.println("======="+getName()+"=======");
for (OrganizationComponent component : components) {
component.print();
}
}
@Override
public String getName() {
return super.getName();
}
}
public class Department extends OrganizationComponent {
private List<OrganizationComponent> components = new ArrayList<>();
public Department(String name) {
super(name);
}
@Override
protected void add(OrganizationComponent component) {
components.add(component);
}
@Override
protected void remove(OrganizationComponent component) {
components.remove(component);
}
@Override
protected void print() {
System.out.println("======="+getName()+"=======");
for (OrganizationComponent component : components) {
component.print();
}
}
@Override
public String getName() {
return super.getName();
}
}
「葉子構件」:Group,葉子構件不沒有子節點了,所以不需要添加、洗掉之類的方法
public class Group extends OrganizationComponent {
public Group(String name) {
super(name);
}
@Override
protected void print() {
System.out.println(getName());
}
@Override
public String getName() {
return super.getName();
}
}
「測驗類」:Client
public class Client {
@Test
public void test01(){
OrganizationComponent company = new Company("阿里巴巴");
OrganizationComponent department1 = new Department("市場部");
OrganizationComponent department2 = new Department("技術部");
OrganizationComponent group1 = new Group("市場一組");
OrganizationComponent group2 = new Group("市場二組");
OrganizationComponent group3 = new Group("技術一組");
OrganizationComponent group4 = new Group("技術二組");
//添加部門
company.add(department1);
company.add(department2);
//添加小組
department1.add(group1);
department1.add(group2);
department2.add(group3);
department2.add(group4);
//列印結果
company.print();
}
}
「運行結果」
=======阿里巴巴=======
=======市場部=======
市場一組
市場二組
=======技術部=======
技術一組
技術二組
在 HashMap 中的應用
在 Java(jdk 1.8為例) 的集合類 HashMap 中,抽象構件是 Map,容器構件是 HashMap,葉子構件是 Node
進入原始碼可以看見,在 Map 中定義了許多公共方法

HashMap 實作了 Map,并對一些方法重寫,而且 HashMap 中有一個靜態內部類 Node,它就充當了葉子構件的角色,Node 中去除了 put、putAll 等方法,下面也沒有子結點了
使用:
@Test
public void test02(){
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", "v2");
System.out.println(map);
}
當我們 put 一個鍵值對的時候,在 HashMap 內部會呼叫 putVal 方法,將鍵值對封裝為 Node,
總結
1、簡化客戶端操作,客戶端只需要面對一致的物件而不用考慮整體部分或者節點葉子的問題,
2、具有較強的擴展性,當我們要更改組合物件時,我們只需要調整內部的層次關系,客戶端不用做出任何改動,
3、方便創建出復雜的層次結構,客戶端不用理會組合里面的組成細節,容易添加節點或者葉子從而創建出復雜的樹形結構,
4、需要遍歷組織機構,或者處理的物件具有樹形結構時,非常適合使用組合模式,
5、要求較高的抽象性,如果節點和葉子有很多差異性的話,比如很多方法和屬性都不一樣,不適合使用組合模式,
p.s. 所有代碼和筆記均可在 我的GitHub 中獲取,如果對您有幫助的話,可以點個 star 支持一下 ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/16321.html
標籤:設計模式
下一篇:原型模式
