1、概述java
容許你將對象組合成樹形結構來表現「總體/部分」層次結構。組合能讓客戶以一致的方式處理個別對象以及組合對象。網絡
2、解決問題ide
組合模式解決這樣的問題,當咱們的要處理的對象能夠生成一顆樹形結構,而咱們要對樹上的節點和葉子進行操做時,它可以提供一致的方式,而不用考慮它是節點仍是葉子。測試
3、結構類圖this
4、應用實例spa
上一講中,咱們是以大學的院系結構來說解迭代器的,在組合模式中,咱們仍是引用這個例子。把學校做爲根節點,學院作普通節點,專業就是葉子。code
首先,從上面的類圖中知道,對於客戶端來講,其須要面對的就是一個組件,而不用管是否節點仍是葉子。咱們就先來建立這樣一個組件對象
package com.jet.pattern.Composite; /** * description: * 機構組件,學院和系稱爲機構 * Created by Administrator on 2016/11/17. */ public abstract class OrganizationComponent { // 每一個方法提供默認的實現 public void add(OrganizationComponent organizationComponent){ throw new UnsupportedOperationException(); } public void remove(OrganizationComponent organizationComponent){ throw new UnsupportedOperationException(); } public String getName(){ throw new UnsupportedOperationException(); } public String getDescription(){ throw new UnsupportedOperationException(); } public void print(){ throw new UnsupportedOperationException(); } }
接着從上到下建立組件對象,建立學校對象blog
package com.jet.pattern.Composite.impl; import com.jet.pattern.Composite.OrganizationComponent; import java.util.ArrayList; import java.util.List; /** * description: * 大學對象 * Created by Administrator on 2017/1/13. */ public class University extends OrganizationComponent { String name; String description; List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>(); public University(String name, String description) { this.name = name; this.description = description; } // 重寫機構組件的方法,其做爲樹有增長和刪除方法 @Override public void add(OrganizationComponent organizationComponent) { organizationComponents.add(organizationComponent); } @Override public void remove(OrganizationComponent organizationComponent) { organizationComponents.remove(organizationComponent); } @Override public String getName() { return name; } @Override public String getDescription() { return description; } @Override public void print() { System.out.println("-------" + getName() + "-----------"); // 大學下面有不少學院,把他們遍歷出來 for(OrganizationComponent organizationComponent : organizationComponents){ organizationComponent.print(); } } }
建立學院對象ip
package com.jet.pattern.Composite.impl; import com.jet.pattern.Composite.OrganizationComponent; import java.util.ArrayList; import java.util.List; /** * description: * 學院是一個機構, * Created by Administrator on 2017/1/13. */ public class College extends OrganizationComponent { String name; String description; List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>(); public College(String name, String description) { this.name = name; this.description = description; } // 重寫機構組件的方法,其做爲樹有增長和刪除方法 @Override public void add(OrganizationComponent organizationComponent) { organizationComponents.add(organizationComponent); } @Override public void remove(OrganizationComponent organizationComponent) { organizationComponents.remove(organizationComponent); } @Override public String getName() { return name; } @Override public String getDescription() { return description; } @Override public void print() { System.out.println("-------" + getName() + "-----------"); // 學院下面有不少專業,把他們遍歷出來 for(OrganizationComponent organizationComponent : organizationComponents){ organizationComponent.print(); } } }
建立專業(系)對象
package com.jet.pattern.Composite.impl; import com.jet.pattern.Composite.OrganizationComponent; /** * description: * 專業(系)對象 * Created by Administrator on 2017/1/13. */ public class Department extends OrganizationComponent { String name; String description; public Department(String name, String description) { this.name = name; this.description = description; } // 重寫機構組件的方法,其做爲葉子沒有增長和刪除方法 @Override public String getName() { return name; } @Override public String getDescription() { return description; } // 葉子只須要輸出本身的信息 @Override public void print() { System.out.println(getName()); } }
建立輸出對象,模擬客戶端
package com.jet.pattern.Composite.impl; import com.jet.pattern.Composite.OrganizationComponent; /** * description: * 輸出信息,模擬客戶調用 * Created by Administrator on 2017/1/13. */ public class OutputInfo { OrganizationComponent allOrganization; public OutputInfo(OrganizationComponent allOrganization) { this.allOrganization = allOrganization; } public void printOrganization(){ allOrganization.print(); } }
測試組合模式
package com.jet.pattern.Composite.test; import com.jet.pattern.Composite.OrganizationComponent; import com.jet.pattern.Composite.impl.College; import com.jet.pattern.Composite.impl.Department; import com.jet.pattern.Composite.impl.OutputInfo; import com.jet.pattern.Composite.impl.University; /** * description: * 測試組合模式 * Created by Administrator on 2017/1/13. */ public class CompositeTest { public static void main(String[] args) { // 從大到小建立對象,學院和專業組合成爲學校,先建立學校,它也是機構組件 OrganizationComponent university = new University("清華大學","全國最好的大學"); // 接着建立學院 OrganizationComponent computerCollege = new College("計算機學院","計算機學院"); OrganizationComponent infoEngineeringCollege = new College("信息工程學院","信息工程學院"); // 計算機學院有下面專業 computerCollege.add(new Department("計算機科學與技術","計算機科學與技術")); computerCollege.add(new Department("軟件工程 ","軟件工程")); computerCollege.add(new Department("網絡工程","網絡工程")); // 信息工程學院有下面專業 infoEngineeringCollege.add(new Department("通訊工程","通訊工程")); infoEngineeringCollege.add(new Department("信息工程","信息工程")); // 學校有下面學院 university.add(computerCollege); university.add(infoEngineeringCollege); // 輸出學校機構信息 OutputInfo info = new OutputInfo(university); info.printOrganization(); } }
測試輸出結果以下:
5、使用場景
1.當須要遍歷組織機構,或者處理的對象具備樹形結構時使用。
6、優缺點
1.優勢
(1)、簡化客戶端操做。客戶端只須要面對一致的對象而不用考慮總體部分或者節點葉子的問題。
(2)、具備較強的擴展性。當咱們要更改組合對象時,咱們只須要調整內部的層次關係,客戶端不用作出任何改動。
(3)、方便建立出複雜的層次結構。客戶端不用理會組合裏面的組成細節,容易添加節點或者葉子從而建立出複雜的樹形結構。
2.缺點
(1)、要求較高的抽象性,若是節點和葉子有不少差別性的話,好比不少方法和屬性都不同,難以實現組合模式。