需求中是體現部分與總體層次的結構時,以及你但願用戶能夠忽略組合對象與單個對象的不一樣,統一地使用組合結構中的全部對象時,就應該考慮使用組合模式了——《大話設計模式》html
能夠用於樹結構的數據上,好比公司層級,樹形文件系統等。java
公司架構是總公司下有人力資源部和財務部以及分公司,分公司下有人力資源部和財務部已經下屬的辦事處,辦事處下屬也有人力資源和財務部,對公司架構能夠分析總結出,一共分爲實體公司部門(分支節點),好比分公司、總公司、辦事處,人力資源部門和財務部(葉子節點),各辦事處、分公司都有單獨設置。編程
首先抽象一層公司的描述:設計模式
public abstract class Company { protected String name; public Company(String name) { this.name = name; } public abstract void add(Company c); public abstract void remove(Company c); public abstract void display(int depth); //顯示 public abstract void lineOfDuty(); //履行職責 }
實現一個普通的公司描述:架構
public class ConcreteCompany extends Company { private List<Company> children = new ArrayList(); public ConcreteCompany(String name) { super(name); } @Override public void add(Company c) { children.add(c); } @Override public void remove(Company c) { children.remove(c); } @Override public void display(int depth) { Printer.print(depth, this.name); for (Company c : children) { c.display(depth + 2); } } @Override public void lineOfDuty() { for (Company c : children) { c.lineOfDuty(); } } }
人力資源和財務部的實現:app
public class HrDepartment extends Company { public HrDepartment(String name) { super(name); } @Override public void add(Company c) { } @Override public void remove(Company c) { } @Override public void display(int depth) { Printer.print(depth,this.name); } @Override public void lineOfDuty() { System.out.println(String.format("%s 員工招聘培訓管理", this.name)); } }
public class FinanceDepartment extends Company { public FinanceDepartment(String name) { super(name); } @Override public void add(Company c) { } @Override public void remove(Company c) { } @Override public void display(int depth) { Printer.print(depth, this.name); } @Override public void lineOfDuty() { System.out.println(String.format("%s 公司財務收支管理", this.name)); } }
另外增長一個打印的輔助工具類:ide
public class Printer { public static void print(int dept,String label) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < dept; i++) { builder.append(" - "); } System.out.println(builder.toString() + label); } }
運行上述的例子:工具
@Test public void testComposite(){ ConcreteCompany root = new ConcreteCompany("北京總公司"); root.add(new HrDepartment("總公司人力資源部")); root.add(new FinanceDepartment("總公司財務部")); ConcreteCompany comp = new ConcreteCompany("上海華東分公司"); comp.add(new HrDepartment("華東分公司人力資源部")); comp.add(new FinanceDepartment("華東分公司財務部")); root.add(comp); ConcreteCompany comp1 = new ConcreteCompany("南京辦事處"); comp1.add(new HrDepartment("南京辦事處人力資源部")); comp1.add(new FinanceDepartment("南京辦事處財務部")); comp.add(comp1); ConcreteCompany comp2 = new ConcreteCompany("杭州辦事處"); comp2.add(new HrDepartment("杭州辦事處人力資源部")); comp2.add(new FinanceDepartment("杭州辦事處財務部")); comp.add(comp2); root.display(1); root.lineOfDuty(); }
運行結果爲:ui
- 北京總公司 - - - 總公司人力資源部 - - - 總公司財務部 - - - 上海華東分公司 - - - - - 華東分公司人力資源部 - - - - - 華東分公司財務部 - - - - - 南京辦事處 - - - - - - - 南京辦事處人力資源部 - - - - - - - 南京辦事處財務部 - - - - - 杭州辦事處 - - - - - - - 杭州辦事處人力資源部 - - - - - - - 杭州辦事處財務部 總公司人力資源部 員工招聘培訓管理 總公司財務部 公司財務收支管理 華東分公司人力資源部 員工招聘培訓管理 華東分公司財務部 公司財務收支管理 南京辦事處人力資源部 員工招聘培訓管理 南京辦事處財務部 公司財務收支管理 杭州辦事處人力資源部 員工招聘培訓管理 杭州辦事處財務部 公司財務收支管理 Process finished with exit code 0
組合模式的優勢:this
組合模式的缺點:
在如下狀況下可使用組合模式:
本文參考了《大話設計模式》 和 https://www.cnblogs.com/Bobby0322/p/4191895.html