組合模式

定義

允許你將對(duì)象組合成樹形結(jié)構(gòu)來表現(xiàn)“整體/部分”層次結(jié)構(gòu)。組合能讓客戶以一致的方式處理個(gè)別對(duì)象以及對(duì)象組合。

使用場(chǎng)景

  • 表示對(duì)象的部分 - 整體層次
  • 客戶端能夠忽略對(duì)象和單個(gè)對(duì)象的組合之間的差異。 客戶端將統(tǒng)一處理復(fù)合結(jié)構(gòu)中的所有對(duì)象

例子

我們要打印一封信的內(nèi)容。信的內(nèi)容是由句子(sentence)組成,句子由單詞(word)組成,單詞由字母(letter)組成淮摔。遇到字母直接打印出來,單詞的前面輸出空格始赎,句子的末尾輸出句號(hào)和橙。三個(gè)對(duì)象繼承同一對(duì)象,其print方法是一樣的造垛,對(duì)外來看是沒有差別的魔招。
字母組合基類,其包括添加子元素筋搏、迭代執(zhí)行打悠桶佟:

public abstract class LetterComposite {
  private List<LetterComposite> children = new ArrayList<>();

  public void add(LetterComposite letter) {
    children.add(letter);
  }

  protected abstract void printThisBefore();
  protected abstract void printThisAfter();

  // 打印的時(shí)候 迭代執(zhí)行
  public void print() {
    printThisBefore();
    for (LetterComposite letter : children) {
      letter.print();
    }
    printThisAfter();
  }
}

字母類重寫了printThisBefore方法,此方法打印字母本身:

public class Letter extends LetterComposite {
  private char c;

  public Letter(char c) {
    this.c = c;
  }

  protected void printThisBefore() {
    System.out.print(c);
  }

  protected void printThisAfter() {
    // nop
  }
}

單詞類以字母列表為構(gòu)造參數(shù)奔脐,也重寫了printThisBefore方法:

public class Word extends LetterComposite {
  public Word(List<Letter> letters) {
    for (Letter l : letters) {
      this.add(l);
    }
  }

  protected void printThisBefore() {
    System.out.print(" ");
  }

  protected void printThisAfter() {
    // nop
  }
}

句子類以單詞列表為構(gòu)造參數(shù)俄周,printThisAfter在句子末尾輸出".":

public class Sentence extends LetterComposite {
  public Sentence(List<Word> words) {
    for (Word w : words) {
      this.add(w);
    }
  }

  protected void printThisBefore() {
    // nop
  }

  protected void printThisAfter() {
    System.out.print(".");
  }
}

構(gòu)造一個(gè)Message類吁讨,用于創(chuàng)建內(nèi)容:

public class Messenger {
  LetterComposite messageFromOrcs() {
    List<Word> words = new ArrayList<>();
    words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter(
        'r'), new Letter('e'))));
    ...
    words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y'))));
    return new Sentence(words);
  }

  LetterComposite messageFromElves() {
    List<Word> words = new ArrayList<>();
    words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter(
        'h'))));
    ...
    words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter(
        't'), new Letter('h'))));

    return new Sentence(words);
  }
}

打印兩份信的內(nèi)容:

public class App {
  public static void main(String[] args) {
    System.out.println("Message from the orcs: ");
    LetterComposite orcMessage = new Messenger().messageFromOrcs();
    orcMessage.print();

    System.out.println("Message from the elves: ");
    LetterComposite elfMessage = new Messenger().messageFromElves();
    elfMessage.print();
  }
}

分析

上述的例子中,Sentence峦朗、Word建丧、Letter是三個(gè)層級(jí)的對(duì)象,它們構(gòu)成了樹狀結(jié)構(gòu)波势。
組合模式讓我們能用樹形方式創(chuàng)建對(duì)象的結(jié)構(gòu)翎朱,樹里面包含了組合以及個(gè)別的對(duì)象。
使用組合結(jié)構(gòu)尺铣,我們能把相同的操作應(yīng)用在組合和個(gè)別對(duì)象上拴曲。換句話說,在大多數(shù)情況下凛忿,我么可以忽略對(duì)象組合和個(gè)別對(duì)象之間的差別澈灼。

參考

iluwatar/java-design-patterns

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市店溢,隨后出現(xiàn)的幾起案子叁熔,更是在濱河造成了極大的恐慌,老刑警劉巖床牧,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荣回,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡戈咳,警方通過查閱死者的電腦和手機(jī)心软,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來著蛙,“玉大人糯累,你說我怎么就攤上這事〔岵龋” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵效拭,是天一觀的道長(zhǎng)暂吉。 經(jīng)常有香客問我,道長(zhǎng)缎患,這世上最難降的妖魔是什么慕的? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮挤渔,結(jié)果婚禮上肮街,老公的妹妹穿的比我還像新娘。我一直安慰自己判导,他們只是感情好嫉父,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布沛硅。 她就那樣靜靜地躺著,像睡著了一般绕辖。 火紅的嫁衣襯著肌膚如雪摇肌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天仪际,我揣著相機(jī)與錄音围小,去河邊找鬼。 笑死树碱,一個(gè)胖子當(dāng)著我的面吹牛肯适,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播成榜,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼框舔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了伦连?” 一聲冷哼從身側(cè)響起雨饺,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惑淳,沒想到半個(gè)月后额港,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體歧焦,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡移斩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绢馍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片向瓷。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖舰涌,靈堂內(nèi)的尸體忽然破棺而出猖任,到底是詐尸還是另有隱情,我是刑警寧澤瓷耙,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布朱躺,位于F島的核電站,受9級(jí)特大地震影響搁痛,放射性物質(zhì)發(fā)生泄漏长搀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一鸡典、第九天 我趴在偏房一處隱蔽的房頂上張望源请。 院中可真熱鬧,春花似錦、人聲如沸谁尸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽症汹。三九已至硫朦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間背镇,已是汗流浹背咬展。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞒斩,地道東北人破婆。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像胸囱,于是被迫代替她去往敵國(guó)和親祷舀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容