組合模式關注那些存在於葉子構件和容器構件的結構以及它們的組織形式,葉子構件中不能包含成員對象,容器構件中能夠包含成員對象,這些成員對象多是葉子構件對象,也多是容器構件對象。這些對象能夠構成一個樹形結構,組合模式是用面向對象的方法處理樹形結構。java
在Windows操做系統的文件目錄結構包含文件和文件夾兩類對象,其中在文件夾能夠包含子文件夾,也能夠包含文件。文件夾是容器類,而不一樣類型的各類文件是成員類,也稱爲葉子類,一個文件夾也能夠做爲另外一個更大的文件夾的成員。組合模式描述瞭如何將容器對象和葉子對象進行遞歸組合,使得用戶在使用時無須對它們進行區分,能夠作到一致對待容器對象和葉子對象。算法
組合多個對象造成樹形結構以表示「總體-部分」的結構層次。編程
Component(抽象構件)安全
抽象構件能夠是接口或抽象類,爲葉子構件和容器構件對象聲明接口,在該角色中能夠包含全部子類共有行爲的聲明和實現。在抽象構件在定義了訪問及管理它的子構件的方法,如增長子構件、刪除子構件、獲取子構件等。ide
Leaf(葉子構件)操作系統
葉子構件在組合結構中表示葉子節點對象,葉子節點沒有子節點,實如今抽象構件中定義的行爲。對於訪問及管理子構件的方法,能夠經過異常等方式進行處理。設計
Composite(容器構件)code
容器構件在組合結構中表示容器節點對象,容器節點包含子節點,其子節點能夠是葉子節點,也能夠是容器節點,它提供一個集合用於存儲子節點,實如今抽象構件中定義的行爲,包括那些訪問及管理子構件的方法,在其業務方法中能夠遞歸調用其子節點的業務方法。對象
Client(客戶類)blog
客戶類是能夠經過抽象構件接口訪問和控制組合構件中的對象。
組合模式的關鍵是定義一個抽象構件類,它既能夠表明葉子,也能夠表明容器,而客戶端針對該抽象構件類進行編程,無須知道它究竟是葉子仍是容器,能夠對其進行統一處理。
通常抽象構件類設計爲接口或抽象類,將全部子類共有方法聲明和實現放在抽象構件類中。對於客戶端編程,將針對抽象構件編程,而無須關心其具體子類是容器構件仍是葉子構件。
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類中聲明這些用於管理成員對象的方法。對於葉子對象,客戶端不可能調用到管理成員對象的方法。缺點是不夠透明,客戶端不能徹底針對抽象編程。