- 概述
- UML類(lèi)圖
- 代碼栗子
- 總結(jié)
-
概述
概念 組合模式是指將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶(hù)對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。
-
作用:讓客戶(hù)端不再區(qū)分操作的是組合對(duì)象還是葉子對(duì)象,而是以一個(gè)統(tǒng)一的方式來(lái)操作。
UML類(lèi)圖
-
代碼栗子
栗子 主管與下屬
-
code
public interface ICorp { /** * 獲取員工信息 * @return */ String getInfo() ; } //葉子節(jié)點(diǎn) public interface ILeaf extends ICorp{ /** * 獲取員工信息 * @return */ @Override String getInfo() ; } //樹(shù)枝 public interface IBranch extends ICorp { /** * 增加員工(樹(shù)葉節(jié)點(diǎn))或者是經(jīng)理(樹(shù)枝節(jié)點(diǎn)) * @param corp */ void addSubordinate(ICorp corp); /** * 獲得下屬的信息 * @return */ ArrayList<ICorp> getSubordinate(); }
public class Branch implements IBranch{ /** * 名稱(chēng) */ private String name; /** * 職位 */ private String position; /** * 薪水 */ private int salary; ArrayList<ICorp> subordinateList = new ArrayList<>(); public Branch(String name,String position,int salary){ this.name = name; this.position = position; this.salary = salary; } /** * 增加一個(gè)下屬,可能是小頭目,也可能是個(gè)小兵 * @param corp */ @Override public void addSubordinate(ICorp corp) { this.subordinateList.add(corp); } /** * 我有哪些下屬 * @return */ @Override public ArrayList<ICorp> getSubordinate() { return this.subordinateList; } /** * 領(lǐng)導(dǎo)也是人,他也有信息 * @return */ @Override public String getInfo() { String info = ""; info = "姓名:" + this.name; info = info + "\t職位:"+ this.position; info = info + "\t薪水:" + this.salary; return info; } }
public class Leaf implements ILeaf{ /** * 名稱(chēng) */ private String name; /** * 職位 */ private String position; /** * 薪水 */ private int salary ; public Leaf(String name,String position,int salary){ this.name = name; this.position = position; this.salary = salary; } /** * 獲得小兵的信息 * @return */ @Override public String getInfo() { String info = ""; info = "姓名:" + this.name; info = info + "\t職位:"+ this.position; info = info + "\t薪水:" + this.salary; return info; } }
-
測(cè)試
public class Client { /** * ceo */ private static Branch ceo; /** * 開(kāi)發(fā)經(jīng)理 */ private static Branch developDep; /** * 財(cái)務(wù)經(jīng)理 */ private static Branch financeDep; static { //初始化組織結(jié)構(gòu) ceo = new Branch("馬總", "總經(jīng)理", 100000); developDep = new Branch("張三", "研發(fā)部門(mén)經(jīng)理", 10000); financeDep = new Branch("里斯", "財(cái)務(wù)部經(jīng)理", 20000); Leaf a = new Leaf("a", "開(kāi)發(fā)人員", 2000); Leaf b = new Leaf("b", "開(kāi)發(fā)人員", 2000); Leaf c = new Leaf("c", "開(kāi)發(fā)人員", 2000); Leaf d = new Leaf("d", "財(cái)務(wù)人員", 4000); Leaf e = new Leaf("e", "財(cái)務(wù)人員", 4000); Leaf f = new Leaf("f", "財(cái)務(wù)人員", 4000); ceo.addSubordinate(developDep); ceo.addSubordinate(financeDep); developDep.addSubordinate(a); developDep.addSubordinate(b); developDep.addSubordinate(c); financeDep.addSubordinate(d); financeDep.addSubordinate(e); financeDep.addSubordinate(f); } public static void main(String[] args) { // //首先把CEO的信息打印出來(lái) System.out.println(ceo.getInfo()); //然后是所有員工信息 System.out.println(getTreeInfo(ceo)); } /** * 遍歷整棵樹(shù),只要給我根節(jié)點(diǎn),我就能遍歷出所有的節(jié)點(diǎn) * @param root * @return */ public static String getTreeInfo(Branch root) { ArrayList<ICorp> subordinateList = root.getSubordinate(); String info = ""; for (ICorp s : subordinateList) { /** * 是員工就直接獲得信息 */ if (s instanceof Leaf) { info = info + s.getInfo() + "\n"; } else { //是個(gè)小頭目 info = info + s.getInfo() + "\n" + getTreeInfo((Branch) s); } } return info; } }
-
-
總結(jié)
-
場(chǎng)景
當(dāng)遇到想表示樹(shù)形結(jié)構(gòu)時(shí)(如菜單欄 等),優(yōu)先考慮組合模式
-
缺點(diǎn)
安全性和透明性是互相矛盾的,這是由于葉子節(jié)點(diǎn)和非葉子節(jié)點(diǎn)行為的不一致以及需要提供一個(gè)一致的行為接口所造成的,是不可調(diào)和的矛盾
-
實(shí)際中,組合模式的大多數(shù)使用場(chǎng)景可以通過(guò)表設(shè)計(jì)進(jìn)行規(guī)范解決
ps: 這樣就可以呈現(xiàn)出一個(gè)樹(shù)形結(jié)構(gòu)
-
參考資料
書(shū)籍:《設(shè)計(jì)模式之禪》