上周面試,面試官問橋接模式是什么,我就舉了個例子:手機分為蘋果,小米....,每個手機都有視頻,游戲...等功能。直觀上是一個樹形結構。這種情況下,可以用橋接模式,把手機作為接口,蘋果,小米等繼承手機接口;再用一個手機軟件接口,讓視頻,游戲等繼承手機軟件接口;在手機中保留軟件指針。這樣可以讓具體的手機和手機軟件解耦。然后面試官說,這個case可以用組合模式。我就說不知道組合模式。回來看了一下組合模式。
組合模式:將對象組合成樹形結構以表示“部分-整體”的層次結構,組合模式使得用戶對單個對象和組合對象的使用具有一致性。重點是理解清楚“部分/整體”還有“單個對象”和“組合對象”的含義。在樹形結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以像處理簡單元素一樣處理復雜元素,從而使得客戶程序與復雜元素的內部解耦。
角色:
1:Component 是組合中的對象聲明接口,在適當的情況下,實現所有類公有接口的默認行為。聲明一個接口用於訪問和管理Component子部件。
2:Leaf 在組合中表示葉子節點對象,葉子節點沒有子節點。
3:Composite定義有枝節點行為,用來存儲子部件,在Component接口中實現與子部件有關操作,如add和remove等。

應用場景:
1:想表示對象的部分-整體層次結構。
2:希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。
經典案例:系統目錄結構,網站導航結構,文件系統。
代碼示意:做一套辦公管理系統,並且總公司的人力資源部、財務部等的辦公掛歷功能在所有的分公司都有。

// 公司的抽象類或接口(Component)
public abstract class Company {
protected String name;
public Company(String name)
{
this.name = name;
}
public abstract void add(Company company);
public abstract void remove(Company company);
public abstract void display(int depth);
public abstract void lineofDuty();
}
// 具體公司類,是樹枝節點(Composite)
import java.util.ArrayList;
import java.util.List;
public class ConcreteCompany extends Company {
private List<Company> childrenCompany = new ArrayList<Company>();
public ConcreteCompany(String name) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
public void add(Company company) {
childrenCompany.add(company);
}
@Override
public void remove(Company company) {
childrenCompany.remove(company);
}
@Override
public void display(int depth) {
}
@Override
public void lineofDuty() {
}
}
// 財務部和人力資源部門(leaf)
public class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int depth) {
}
@Override
public void lineofDuty() {
System.out.println(name + " 負責公司財務收支管理");
}
}
public class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int depth) {
}
@Override
public void lineofDuty() {
System.out.println(name + " 負責員工招聘管理培訓");
}
}
// 測試類
public class CompositePatternDemo {
public static void main(String[] args) {
// 一個總公司,包含HR部門和財務部門
ConcreteCompany root = new ConcreteCompany("北京總公司");
root.add(new HRDepartment("總公司人力資源部"));
root.add(new FinanceDepartment("總公司財務部"));
//2個子公司,每個子公司都有HR部門和財務部門
ConcreteCompany com1 = new ConcreteCompany("廣州分公司");
com1.add(new HRDepartment("廣州分公司人力資源部"));
com1.add(new FinanceDepartment("廣州分公司財務部"));
root.add(com1);
ConcreteCompany com2 = new ConcreteCompany("杭州分公司");
com2.add(new HRDepartment("杭州分公司人力資源部"));
com2.add(new FinanceDepartment("杭州分公司財務部"));
root.add(com2);
}
}
總結:
優點: 節點可以自由增加。
客戶調用簡單,統一的方式調用。
缺點: 葉子(leaf)和樹枝節點(Composite)都是實現類,而不是接口,違反了依賴倒置原則。
