<<設(shè)計(jì)模式之禪(第二版)>>——第二十一章 組合模式

定義:
  • 將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。
組合模式通用類圖
/*
 * 創(chuàng)建抽象構(gòu)建
 * */
public abstract class Component {
  // 個(gè)體和整體共有的方法
  public void doSomething() {

  }
}

/*
 * 創(chuàng)建樹枝組件
 * */
public class Composite extends Component {
  // 構(gòu)架容器
  private ArrayList<Component> componentArrayList = new ArrayList<>();

  public void add(Component component) {
    this.componentArrayList.add(component);
  }

  public void remove(Component component) {
    this.componentArrayList.remove(component);
  }

  public ArrayList<Component> getChildren() {
    return this.componentArrayList;
  }
}

/*
 * 創(chuàng)建最小的組件
 * */
public class Leaf extends Component {
  @Override
  public void doSomething() {
    // TODO Auto-generated method stub
    super.doSomething();
  }
}
public class Client {
  public static void main(String[] args) {
    // 創(chuàng)建根節(jié)點(diǎn)
    Composite root = new Composite();
    // 創(chuàng)建樹枝節(jié)點(diǎn)
    Composite branch = new Composite();
    // 創(chuàng)建樹葉
    Leaf leaf = new Leaf();// 違反依賴倒轉(zhuǎn)原則
    root.add(branch);
    branch.add(leaf);
  }

  // 遞歸遍歷節(jié)點(diǎn)
  public static void display(Composite root) {
    for (Component c : root.getChildren()) {
        if (c instanceof Leaf) {
            c.doSomething();
        } else {
            display((Composite) c);
        }
    }
  }
}
優(yōu)點(diǎn):
  • 高層模塊的調(diào)用簡單,所有的節(jié)點(diǎn)都是Component,局部和整體對(duì)調(diào)用者來說沒有任何區(qū)別,高層模塊不關(guān)心自己處理的是單個(gè)對(duì)象還是整個(gè)組合結(jié)構(gòu),簡化了高層模塊的代碼。
  • 節(jié)點(diǎn)自由增加
缺點(diǎn):
  • 定義時(shí)候直接使用的是實(shí)現(xiàn)類,這在面向接口編程上是很不恰當(dāng)?shù)模c依賴倒置原則沖突。
組合模式的拓展:
  • 透明的組合模式(透明模式是把用來組合使用的方法放到抽象類中,通過判斷getChildren的返回值確認(rèn)是葉子節(jié)點(diǎn)還是書直接點(diǎn),如果處理不當(dāng),這個(gè)會(huì)在運(yùn)行期間出現(xiàn)問題):
透明模式的通用類圖
public abstract class Component {
  public void doSomething() {

  }

  public abstract void add(Component component);

  public abstract void remove(Component component);

  public abstract ArrayList<Component> getChildren();
}

public class Leaf extends Component {

  @Deprecated
  public void add(Component component) {
    // TODO Auto-generated method stub
    throw new UnsupportedOperationException();
  }

  @Deprecated
  public void remove(Component component) {
    // TODO Auto-generated method stub
    throw new UnsupportedOperationException();
  }

  @Deprecated
  public ArrayList<Component> getChildren() {
    // TODO Auto-generated method stub
    throw new UnsupportedOperationException();
  }

}

public class Client {
  public static void main(String[] args) {

  }

  public static void display(Component root) {
    for (Component c : root.getChildren()) {
        if (c instanceof Leaf) {
            c.doSomething();
        } else {
            /*
             * 不再使用強(qiáng)制類型轉(zhuǎn)換,遵循依賴倒轉(zhuǎn)原則
             */
            display(c);
        }
    }
  }
}
  • 組合模式的遍歷(可以通過在節(jié)點(diǎn)中添加對(duì)應(yīng)的父節(jié)點(diǎn)對(duì)象信息,使得從子節(jié)點(diǎn)遍歷的時(shí)候可以查詢到相關(guān)的父節(jié)點(diǎn)信息)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 場景問題# 1.1 商品類別樹## 考慮這樣一個(gè)實(shí)際的應(yīng)用:管理商品類別樹。 在實(shí)現(xiàn)跟商品有關(guān)的應(yīng)用系統(tǒng)的時(shí)候...
    七寸知架構(gòu)閱讀 6,293評(píng)論 10 59
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,094評(píng)論 1 15
  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP),是說軟件實(shí)體(類、模塊、函數(shù)等等)應(yīng)該可以拓展,但是不可修改。開-閉原...
    西山薄涼閱讀 4,082評(píng)論 3 14
  • PriorityQueue源碼學(xué)習(xí) 使用堆來實(shí)現(xiàn)一個(gè)優(yōu)先級(jí)隊(duì)列,comapreTo()比較最小的那個(gè)放在堆頂,每次...
    senninha閱讀 664評(píng)論 6 0
  • ?曾經(jīng)有首《寧靜的夏天》,知了也睡了,安心的睡了,在我心里面,寧靜的夏天、、、、、、 因?yàn)橹耍奶觳⒉粚庫o,相反...
    12月32號(hào)閱讀 181評(píng)論 8 6

友情鏈接更多精彩內(nèi)容