在開發中存在不少總體和部分的關係,這個方式最大的體現就是樹形結構。組合模式就是爲了更好地解決這類業務場景的問題。先看下組合模式的定義:ide
將對象組合成樹形結構以表示「總體—部分」的層次關係。組合模式使得用戶對單個對象和組合對象的使用具備一致性。從定義中能夠看出來組合二模式主要有兩點; this
一、總體 - 部分 之間業務結構用樹形表示。spa
二、讓組合對象和各個對象的使用具備一致性。code
總體和部分的結構在生活中太普遍了,好比國家行政級別 中國 ,***省,**市 。學校管級別、公司管理組織機構等,下面以公司組織機構爲例,來看看組合模式。對象
根據這個公司組織結構的圖片,來引進助興結構的專業名詞:總經理稱之爲 root 根節點,財務經理、技術經理、開發組長稱之爲 樹枝節點(branch),財務專員、祕書稱之爲 葉子節點(leaf)。blog
而具體到代碼的實現層面就是,組合模式的核心關鍵就是把這三個對象實現相同的接口,無論是在組件過程,仍是後面的遍歷,全部的節點都用相同的接口,使得對樹形結構的操做更加方便。繼承
接着介紹組合模式的組成元素接口
接下來吧上圖中例子實現如下,可以更直觀瞭解組合模式圖片
// 至關因而 Component public abstract class Zhiwei { protected String name; protected String position; protected float salary; public Zhiwei(String name,String position,float salary){ this.name = name; this.position = position; this.salary = salary; } public abstract void addChild(Zhiwei zhiwei); public abstract void removeChild(Zhiwei zhiwei); public abstract void display(String empty); } //至關因而 Composite public class LingDao extends Zhiwei { private ArrayList<Zhiwei> children = new ArrayList<Zhiwei>(); public LingDao(String name,String position,float salary){ super(name,position,salary); } @Override public void addChild(Zhiwei zhiwei) { // TODO Auto-generated method stub children.add(zhiwei); } @Override public void removeChild(Zhiwei zhiwei) { // TODO Auto-generated method stub children.remove(zhiwei); } @Override public void display(String empty) { // TODO Auto-generated method stub System.out.println(empty+"職位:"+this.position+" 姓名:"+this.name+" 薪水:"+this.salary); for (Zhiwei zhiwei : children) { zhiwei.display(empty+" "); } } } //普通職員 public class Leaf extends Zhiwei { public Leaf(String name, String position, float salary) { super(name, position, salary); // TODO Auto-generated constructor stub } @Override public void addChild(Zhiwei zhiwei) { // TODO Auto-generated method stub System.out.println("cannot add zhiwei to leaf"); } @Override public void removeChild(Zhiwei zhiwei) { // TODO Auto-generated method stub } @Override public void display(String empty) { // TODO Auto-generated method stub System.out.println(empty+"職位:"+this.position+" 姓名:"+this.name+" 薪水:"+this.salary); } } //客戶端 public class Client { public static void main(String[] args) { Zhiwei leader = new LingDao("張無忌","總經理",100000); Zhiwei manager = new LingDao("楊逍", "技術經理", 50000); Zhiwei managerB = new LingDao("範瑤","財務經理",50000); Zhiwei managerC = new LingDao("吳勁草","技術組長",20000); Zhiwei Employee = new LingDao("小昭","祕書",8000); Zhiwei EmployeeA = new LingDao("天字門","財務A",5000); Zhiwei EmployeeX = new LingDao("地字門","財務B",5200); Zhiwei EmployeeC = new LingDao("風字門","開發A",8800); Zhiwei EmployeeD = new LingDao("雷字門","開發B",8400); leader.addChild(manager); leader.addChild(managerB); leader.addChild(Employee); manager.addChild(managerC); manager.addChild(EmployeeC); managerC.addChild(EmployeeD); leader.display(""); } } /********************控制檯************************/ - 職位:總經理 姓名:張無忌 薪水:100000.0 - 職位:技術經理 姓名:楊逍 薪水:50000.0 - 職位:技術組長 姓名:吳勁草 薪水:20000.0 - 職位:開發B 職位:雷字門 薪水:8400.0 - 職位:開發A 姓名:風字門 薪水:8800.0 - 職位:財務經理 姓名:範瑤 薪水:50000.0 - 職位:財務A 姓名:風字門 薪水:5000.0 - 職位:財務B 姓名:地字門 薪水:5200.0 - 職位:祕書 姓名:小昭 薪水:8000.0
經過這個例子能夠看出來,不一樣級別的節點經過同一接口在客戶端試用是很是方便的,調用的時候不用管他表明的是什麼節點。由於可以同一試用。只是在 leaf 級別的節點中,考慮 addChild 、removeChild 給出錯誤提示便可。開發
咱們進一步來分析組合模式的應用場景,除了在很明顯的樹形結構業務中用,在發揮咱們的發散能力,應該可以想到,只要擁有父子關係的場景中都是能夠用的,好比窗體打開的父子窗口、各類單位的人事制度的組織結構、文件管理系統、軟件系統的樹形結構導航。
在思考了組合模式的應用場景後,在考慮下組合模式的優點:
一、定義了實現不一樣層次的對象的統一接口,對象行爲更具備一致性。使得客戶端調用比較簡單。
二、實現了整個業務場景的類層級的所屬關係,經過類裏面的 list 來實現。
三、類實現更具通常性,使得代碼更具備可擴展性。主要表如今新定義的 composite 和 leaf 繼承了統一的操做接口,客戶端就不用改變。
組合模式應用場景是具備父子結構的場景,典型的就是樹形結構。模式的本質就是對不一樣級別的節點對象引入統一的接口,對不一樣級別對象調用、操做具備了一致性。