1. 組合模式
1.1 簡介
??Composite模式揪漩,即組合模式旋恼,又叫部分整體模式。Composite模式將對(duì)象以樹形結(jié)構(gòu)組織起來,以達(dá)成“部分-整體” 的層次結(jié)構(gòu)氢拥,使得客戶端對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性蚌铜。
??Composite模式很容易聯(lián)想到樹形結(jié)構(gòu)圖锨侯。組合體內(nèi)這些對(duì)象都有共同接口,當(dāng)組合體一個(gè)對(duì)象的方法被調(diào)用執(zhí)行時(shí),Composite將遍歷(Iterator)整個(gè)樹形結(jié)構(gòu),尋找同樣包含這個(gè)方法的對(duì)象并實(shí)現(xiàn)調(diào)用執(zhí)行冬殃,牽一動(dòng)百囚痴。所以Composite模式使用到Iterator模式,和Chain of Responsibility模式類似审葬。
1.2 結(jié)構(gòu)
Composite模式uml:
Composite模式角色:
- Component 是組合中的對(duì)象聲明接口深滚,在適當(dāng)?shù)那闆r下,實(shí)現(xiàn)所有類共有接口的默認(rèn)行為涣觉。聲明一個(gè)接口用于訪問和管理Component子部件痴荐。
- Leaf 在組合中表示葉子結(jié)點(diǎn)對(duì)象,葉子結(jié)點(diǎn)沒有子結(jié)點(diǎn)官册。
- Composite 定義有枝節(jié)點(diǎn)行為生兆,用來存儲(chǔ)子部件,在Component接口中實(shí)現(xiàn)與子部件有關(guān)操作膝宁,如增加(add)和刪除(remove)等鸦难。
2. Composite模式示例
??我們以公司和公司下各部門為例,一個(gè)公司一般會(huì)包括hr部門员淫、業(yè)務(wù)部門合蔽、財(cái)務(wù)部門和法務(wù)部門,各部門承擔(dān)不同職責(zé)各司其職介返。公司即是Composite拴事,公司下各部門則是Leaf,公司可以增加刪除部門圣蝎,同時(shí)對(duì)各部門的工作進(jìn)行指導(dǎo)刃宵。
Component(抽象公司):
public abstract class AbstractCompany {
protected String name;
public AbstractCompany(String name) {
this.name = name;
}
public boolean add(AbstractCompany company);
public boolean remove(AbstractCompany company);
public void display(int depth);
public void LineOfDuty();
}
google公司:
public class Google extends AbstractCompany {
public Google(String name) {
super(name);
}
private List<AbstractCompany> children = new ArrayList<>();
public boolean add(AbstractCompany company) {
return children.add(company);
}
public boolean remove(AbstractCompany company) {
return children.remove(company);
}
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + name);
//遞歸調(diào)用子節(jié)點(diǎn)
for (AbstractCompany child : children) {
child.display(depth + 2);
}
}
public void LineOfDuty() {
for (AbstractCompany child : children) {
child.LineOfDuty();
}
}
}
HR部門:
public class HRDepartment extends AbstractCompany {
public HRDepartment(String name) {
super(name);
}
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + name);
}
public void LineOfDuty() {
System.out.println(name + ":員工招聘培訓(xùn)管理");
}
}
業(yè)務(wù)部門:
public class BusinessDepartment extends AbstractCompany {
public BusinessDepartment(String name) {
super(name);
}
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + name);
}
public void LineOfDuty() {
System.out.println(name + ":員工業(yè)務(wù)分配及執(zhí)行");
}
}
法務(wù)部門:
public class LawDepartment extends AbstractCompany {
public LawDepartment(String name) {
super(name);
}
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + name);
}
public void LineOfDuty() {
System.out.println(name + ":公司法律事務(wù)處理");
}
}
財(cái)務(wù)部門:
public class FinanceDepartment extends AbstractCompany {
public FinanceDepartment(String name) {
super(name);
}
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + name);
}
public void LineOfDuty() {
System.out.println(name + ":公司員工工資及業(yè)務(wù)資金結(jié)算");
}
}
客戶端調(diào)用:
public static void main(String[] args) {
AbstractCompany google = new Google("Google");
AbstractCompany hr = new HRDepartment("hr");
AbstractCompany business = new BusinessDepartment("business");
AbstractCompany law = new LawDepartment("law");
AbstractCompany finance = new FinanceDepartment("finance");
google.add(hr);
google.add(business);
google.add(law);
google.add(finance);
google.display(1);
google.LineOfDuty();
}
3. Composite模式總結(jié)
??Composite模式最顯而易見的應(yīng)用即是文件樹,目錄即是Composite捅彻,文件即是Leaf组去。包括以前使用的“容器+內(nèi)容”,其實(shí)是通過組合模式實(shí)現(xiàn)的步淹,組合模式保證了容器和內(nèi)容的一致性从隆,容器里面可以套容器,也可以放內(nèi)容缭裆。
適用場景:
- 想表示對(duì)象的整體與部分的層次結(jié)構(gòu)時(shí)
- 當(dāng)用戶不關(guān)心使用的是組合對(duì)象還是單個(gè)對(duì)象時(shí)(這時(shí)用戶的意圖應(yīng)該是使用他直接或間接手下的所有單個(gè)對(duì)象的相關(guān)行為键闺,但他只會(huì)對(duì)他直接手下下命令)
組合模式特點(diǎn):
- 部分可以被組合成整體,整體也可以被組合成更大的整體澈驼。非葉節(jié)點(diǎn)中存儲(chǔ)的子節(jié)點(diǎn)即可以有葉節(jié)點(diǎn)辛燥,也可以有非葉節(jié)點(diǎn)。
- 用戶可以一致的使用組合對(duì)象(非葉節(jié)點(diǎn))和單個(gè)對(duì)象(葉節(jié)點(diǎn))。(當(dāng)使用組合對(duì)象非增- 刪改查行為時(shí)挎塌,會(huì)自動(dòng)的遞歸調(diào)用組合對(duì)象下的所有葉節(jié)點(diǎn)的對(duì)應(yīng)行為)
- 可以很容易的添加或刪除組件
- 要求較高的抽象性徘六,如果節(jié)點(diǎn)和葉子有很多差異性的話,比如很多方法和屬性都不一樣榴都,難以實(shí)現(xiàn)組合模式