【設計模式從入門到精通】08-組合模式
阿新 • • 發佈:2021-10-24
組合模式
目錄
組合模式
1、學校院系展示需求
編寫程式展示一個學校院系結構:
需求是這樣,要在一個頁面中展示出學校的院系組成,一個學校有多個學院,一個學院有多個系。如圖:
傳統方式解決學校院系展示(類圖)
問題分析
- 1)將學院看做是學校的子類,系是學院的子類,這樣實際上是站在組織大小來進行分層次的
- 2)實際上我們的要求是:在一個頁面中展示出學校的院系組成,一個學校有多個學院,一個學院有多個系。因此這種方案,不能很好實現的 管理
- 3)解決方案:把學校、院、系都看做是組織結構,他們之間沒有繼承的關係,而是一個樹形結構,可以更好的實現管理操作 ==> 組合模式
2、組合模式基本介紹
- 1)組合模式(Composite Pattern),又叫部分整體模式。它建立了物件組的樹形結構,將物件組合成樹狀結構以表示“整體-部分”的層次關係
- 2)組合模式依據樹形結構來組合物件,用來表示部分以及整體層次
- 3)這種型別的設計模式屬於結構型模式
- 4)組合模式使得使用者對單個物件和組合物件的訪問具有一致性,即:組合能讓客戶以一致的方式處理個別對象以及組合物件
原理類圖
對原理結構圖的說明一即組合模式的角色及職責
- 1)
Component
:這是組合中物件宣告介面。在適當情況下,實現所有類共有的介面預設行為,用於訪問和管理Component
子部件。Component
可以是抽象類或者介面 - 2)
Leaf
:在組合中表示葉子結點,葉子結點沒有子節點 - 3)
Composite
:非葉子結點,用於儲存子部件,在Component
介面中實現子部件的相關操作。比如增加、刪除
解決的問題
組合模式解決這樣的問題,當我們的要處理的物件可以生成一棵樹形結構,而我們要對樹上的節點和葉子進行操作時,它能夠提供一致的方式,而不用考慮它是節點還是葉子
3、組合模式解決學校院系展示
UML 類圖
核心程式碼
// Component 抽象類 public abstract class OrganizationComponent { private String name; public OrganizationComponent(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void add(OrganizationComponent organizationComponent) { throw new UnsupportedOperationException(); } public void remove(OrganizationComponent organizationComponent) { throw new UnsupportedOperationException(); } public abstract void print(); } // Composite 非葉子節點 public class University extends OrganizationComponent { List<organizationcomponent> organizationComponentList = new ArrayList<>(); public University(String name) { super(name); } @Override public void add(OrganizationComponent organizationComponent) { organizationComponentList.add(organizationComponent); } @Override public void remove(OrganizationComponent organizationComponent) { organizationComponent.remove(organizationComponent); } @Override public void print() { for (OrganizationComponent organizationComponent : organizationComponentList) { organizationComponent.print(); } } } public class College extends OrganizationComponent { List<organizationcomponent> organizationComponentList = new ArrayList<>(); public College(String name) { super(name); } @Override public void add(OrganizationComponent organizationComponent) { organizationComponentList.add(organizationComponent); } @Override public void remove(OrganizationComponent organizationComponent) { organizationComponent.remove(organizationComponent); } @Override public void print() { System.out.println("=============" + getName() + "============="); for (OrganizationComponent organizationComponent : organizationComponentList) { organizationComponent.print(); } } } // Leaf 葉子結點 public class Major extends OrganizationComponent { public Major(String name) { super(name); } @Override public void print() { System.out.println(getName()); } } // 客戶端 public class Client { public static void main(String[] args) { //大學 OrganizationComponent university = new University("清華大學"); //學院 OrganizationComponent computerCollege = new College("計算機學院"); OrganizationComponent infoEngineerCollege = new College("資訊工程學院"); //專業 computerCollege.add(new Major("軟體工程")); computerCollege.add(new Major("網路工程")); computerCollege.add(new Major("電腦科學與技術")); infoEngineerCollege.add(new Major("通訊工程")); infoEngineerCollege.add(new Major("資訊工程")); university.add(computerCollege); university.add(infoEngineerCollege); university.print(); //=============計算機學院============= //軟體工程 //網路工程 //電腦科學與技術 //=============資訊工程學院============= //通訊工程 //資訊工程 } }
4、JDK 原始碼分析
Java 的集合類—— HashMap 就使用了組合模式
UML 類圖
核心程式碼
// Component
public interface Map<k,v> {
interface Entry<k,v> {}
}
public abstract class AbstractMap<k,v> implements Map<k,v> {}
// Composite
public class HashMap<k,v> extends AbstractMap<k,v> implements Map<k,v>, Cloneable, Serializable {
// Leaf
static class Node<k,v> implements Map.Entry<k,v> {}
}
說明
- 1)Map 就是一個抽象的構建,類似
Component
- 2)HashMap 是一箇中間的構建,類似
Composite
,實現 / 繼承了相關方法 put、putAll - 3)Node 是 HashMap 的靜態內部類,類似
Leaf
葉子節點,這裡就沒有 put
5、注意事項和細節
- 1)簡化客戶端操作:客戶端只需要面對一致的物件,而不用考慮整體部分或者節點葉子的問題
- 2)具有較強擴充套件性:當我們要更改組合物件時,我們只需要調整內部的層次關係,客戶端不用做出任何改動
- 3)方便建立複雜的層次結構:客戶端不用理會組合裡面的組成細節,容易新增節點或者葉子,從而創建出複雜的樹形結構
- 4)需要遍歷組織機構,或者處理的物件具有樹形結構時,非常適合使用組合模式
- 5)要求較高的抽象性,如果節點和葉子有很多差異性的話,比如很多方法和屬性都不一樣,不適合使用組合模式