組合模式關注那些存在于葉子構件和容器構件的結構以及它們的組織形式,葉子構件中不能包含成員物件,容器構件中可以包含成員物件,這些成員物件可能是葉子構件物件,也可能是容器構件物件,這些物件可以構成一個樹形結構,組合模式是用面向物件的方法處理樹形結構,
模式動機
在Windows作業系統的檔案目錄結構包含檔案和檔案夾兩類物件,其中在檔案夾可以包含子檔案夾,也可以包含檔案,檔案夾是容器類,而不同型別的各種檔案是成員類,也稱為葉子類,一個檔案夾也可以作為另一個更大的檔案夾的成員,組合模式描述了如何將容器物件和葉子物件進行遞回組合,使得用戶在使用時無須對它們進行區分,可以做到一致對待容器物件和葉子物件,
模式定義
組合多個物件形成樹形結構以表示“整體-部分”的結構層次,
模式結構

-
Component(抽象構件)
抽象構件可以是介面或抽象類,為葉子構件和容器構件物件宣告介面,在該角色中可以包含所有子類共有行為的宣告和實作,在抽象構件在定義了訪問及管理它的子構件的方法,如增加子構件、洗掉子構件、獲取子構件等,
-
Leaf(葉子構件)
葉子構件在組合結構中表示葉子節點物件,葉子節點沒有子節點,實作在抽象構件中定義的行為,對于訪問及管理子構件的方法,可以通過例外等方式進行處理,
-
Composite(容器構件)
容器構件在組合結構中表示容器節點物件,容器節點包含子節點,其子節點可以是葉子節點,也可以是容器節點,它提供一個集合用于存盤子節點,實作在抽象構件中定義的行為,包括那些訪問及管理子構件的方法,在其業務方法中可以遞回呼叫其子節點的業務方法,
-
Client(客戶類)
客戶類是可以通過抽象構件介面訪問和控制組合構件中的物件,
模式分析
組合模式的關鍵是定義一個抽象構件類,它既可以代表葉子,也可以代表容器,而客戶端針對該抽象構件類進行編程,無須知道它到底是葉子還是容器,可以對其進行統一處理,
一般抽象構件類設計為介面或抽象類,將所有子類共有方法宣告和實作放在抽象構件類中,對于客戶端編程,將針對抽象構件編程,而無須關心其具體子類是容器構件還是葉子構件,
public abstract class Component {
public abstract void add(Component c);
public abstract void remove(Component c);
public abstract Component getChild(int i);
public abstract void operation();
}
繼承抽象構件的是葉子構件則典型代碼如下,葉子構件需要實作抽象構建類中宣告的所有方法,包括業務方法以及管理和訪問子構件的方法,但是葉子構件不包含子構件,因此在在客戶端呼叫葉子構件的子構件管理和訪問方法時需提供例外處理或錯誤提示,
public class Leaf extends Component {
@Override
public void add(Component c) {
//例外處理或錯誤提示
}
@Override
public void remove(Component c) {
//例外處理或錯誤提示
}
@Override
public Component getChild(int i) {
//例外處理或錯誤提示
return null;
}
@Override
public void operation() {
//實作代碼
}
}
容器構件需要實作抽象構建類中宣告的所有方法,包括具體實作業務方法以及管理和訪問子構件的方法,由于容器構件充當的是容器角色,包含成員構件,因此它將呼叫其成員構件的業務方法,使用遞回演算法,即在容器構件的operation()方法中遞回呼叫其成員構件的operation()方法,
public class Composite extends Component {
private ArrayList list = new ArrayList();
@Override
public void add(Component c) {
list.add(c);
}
@Override
public void remove(Component c) {
list.remove(c);
}
@Override
public Component getChild(int i) {
return (Component) list.get(i);
}
@Override
public void operation() {
for (Object o : list) {
((Component) o).operation();
}
}
}
模式優缺點
組合模式優點:
- 組合模式可以清楚地定義分層次的復雜物件,表示物件的全部或部分層次,方便對層次結構進行控制
- 客戶端可以一致的適用組合結構或其中單個物件,用戶不必關心自己處理的是單個物件還是整個組合結構
- 定義了包含葉子物件和容器物件的類的層次結構,葉子物件可以被組合成更復雜的容器物件,而這個容器物件又可以被組合,這樣不斷遞回下去,可以形成復雜的樹形結構
- 更容易在組合體內加入物件構件,客戶端不必因為加入新的物件構件而更改原有代碼
組合模式缺點:
- 使設計變得更加抽象
- 增加新構件時可能會產生一些問題,很難對容器中的構件型別進行限制
模式適用環境
在以下情況下可以使用組合模式:
- 需要表示一個物件整體或部分層次,在具有整體和部分的層次結構中,希望忽略整體與部分的差異,一致地對待它們
- 客戶能忽略不同物件層次的變化,客戶端可以針對抽象構件編程,無須關心物件層次結構的細節
- 物件的結構是動態且復雜程度不一致,但客戶需要一致地處理它們
透明組合模式與安全組合模式
組合模式根據抽象構件類的定義形式,又可分為透明組合模式和安全組合模式
-
透明組合模式
透明組合模式中,抽象構件Component中宣告所有用于管理成員物件的方法,這樣做的好處是確保所有構件類都有相同的介面,在客戶端看來,葉子物件與容器物件所提供的方法是一致的,客戶端可以相同地對待所有的物件,缺點是不夠安全,因為葉子物件和容器物件在本質上是有區別的,

-
安全組合模式
安全組合模式中抽象構件Component中沒有宣告任何用于管理成員物件的方法,而是在Composite類中宣告這些用于管理成員物件的方法,對于葉子物件,客戶端不可能呼叫到管理成員物件的方法,缺點是不夠透明,客戶端不能完全針對抽象編程,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/182460.html
標籤:其他
下一篇:計算機網路--傳輸層
