設(shè)計(jì)模式[11]-組合模式-Composite Pattern

1. 組合模式簡(jiǎn)介

組合模式(Composite Pattern)是結(jié)構(gòu)性設(shè)計(jì)模式,又叫“部分-整體”模式态辛,主要用于樹形結(jié)構(gòu)的處理麸澜。父節(jié)點(diǎn)是整體,子節(jié)點(diǎn)是父節(jié)點(diǎn)的部分奏黑,它們具有相似的行為炊邦。

組合模式的角色一共有三種编矾。

  • Leaf(葉節(jié)點(diǎn)角色): 葉子節(jié)點(diǎn),即沒(méi)有字節(jié)點(diǎn)的節(jié)點(diǎn)馁害,本模式中的“部分”角色洽沟,例如文件系統(tǒng)中文件。

  • Composite(枝節(jié)點(diǎn)角色):枝節(jié)點(diǎn)蜗细,即本模式中的“整體”角色裆操,它包含子節(jié)點(diǎn),字節(jié)點(diǎn)既可以是枝節(jié)點(diǎn)炉媒,也可以是葉節(jié)點(diǎn)踪区;例如文件系統(tǒng)中的文件夾。

  • Component(抽象組件角色): 是組合模式中Composite和Leaf共同的父接口(抽象類)吊骤,在此接口中聲明所有子類的共有的方法缎岗。

2. 組合模式舉例

公司有部門和員工,可以形成一個(gè)樹形結(jié)構(gòu)白粉,如果有一份通知要下發(fā)個(gè)全部的部門传泊,或者某個(gè)事業(yè)部,需要選中對(duì)應(yīng)的節(jié)點(diǎn)鸭巴,即可完成對(duì)該節(jié)點(diǎn)所有子節(jié)點(diǎn)的通知眷细。

序號(hào) 類名 角色 說(shuō)明
1 Node Component 抽象組件角色,抽象節(jié)點(diǎn)
2 Staff Leaf 葉節(jié)點(diǎn)角色鹃祖,員工
3 OrgNode Composite 枝節(jié)點(diǎn)角色溪椎,部門(公司、事業(yè)部)
4 CompisteMain 客戶端 演示調(diào)用恬口,通知發(fā)布
Paste_Image.png

1. Node類

// 抽象組件校读,抽象的組織結(jié)構(gòu)節(jié)點(diǎn)
public interface Node {
    // 增加子節(jié)點(diǎn)
    void add(Node node);
    // 移除子節(jié)點(diǎn)
    void remove(Node node);
    // 獲取第i個(gè)子節(jié)點(diǎn)
    Node get(int i);
    // 發(fā)布通知
    void inform(String information);
}

2. Staff類

// 葉節(jié)沒(méi)有子節(jié)點(diǎn),因此它實(shí)現(xiàn)的add祖能、remove等方法拋出異常歉秫。
public class Staff implements Node {

    private String name;

    public Staff(String name) {
        this.name = name;
    }

    @Override
    public void add(Node node) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void remove(Node node) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Node get(int i) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void inform(String information) {
        System.out.println("員工 [" + name + "] 收到通知:" + information);
    }
}

3. OrgNode

// 枝節(jié)點(diǎn)角色
public class OrgNode implements Node {

    private String name;

    private List<Node> nodeList = new ArrayList<>();

    public OrgNode(String name) {
        this.name = name;
    }

    @Override
    public void add(Node node) {
        nodeList.add(node);
    }

    @Override
    public void remove(Node node) {
        nodeList.remove(node);
    }

    @Override
    public Node get(int i) {
        Node node = null;
        if (i >= 0 && i < nodeList.size()) {
            node = nodeList.get(i);
        }
        return node;
    }
    // 遞歸調(diào)用
    @Override
    public void inform(String information) {
        System.out.println("機(jī)構(gòu) [" + name + "] 收到通知:" + information);
        for (Node node : nodeList) {
            node.inform(information);
        }
    }
}

4. CompositeMain

public class CompisteMain {

    public static void main(String[] args) {
        Node com = new OrgNode("公司");
        Node market = new OrgNode("市場(chǎng)部");
        Node rd = new OrgNode("研發(fā)部");
        Node ceo = new Staff("ceo 王");
        com.add(market);
        com.add(rd);
        com.add(ceo);

        Node steve = new Staff("史蒂夫");
        market.add(steve);

        Node james = new Staff("詹姆斯");
        Node vince  = new Staff("文斯");
        rd.add(james);
        rd.add(vince);

        String infomation = " 1 + 1 = 2  ";
        com.inform(infomation);
    }
}

輸出結(jié)果:

機(jī)構(gòu) [公司] 收到通知: 1 + 1 = 2  
機(jī)構(gòu) [市場(chǎng)部] 收到通知: 1 + 1 = 2  
員工 [史蒂夫] 收到通知: 1 + 1 = 2  
機(jī)構(gòu) [研發(fā)部] 收到通知: 1 + 1 = 2  
員工 [詹姆斯] 收到通知: 1 + 1 = 2  
員工 [文斯] 收到通知: 1 + 1 = 2  
員工 [ceo 王] 收到通知: 1 + 1 = 2  

3. 組合模式總結(jié)

組合模式非常適合樹形結(jié)構(gòu)的處理,當(dāng)要求父節(jié)點(diǎn)和子節(jié)點(diǎn)具有相同的功能的時(shí)候养铸。

但Leaf中實(shí)現(xiàn)了不必要的方法雁芙,客戶端不知道操作的節(jié)點(diǎn)是Leaf還是Composite,可能導(dǎo)致不安全揭厚。

如果抽象組件(例如本例的Node)中僅定義inform方法却特,而把a(bǔ)dd、remove筛圆、get等放入Composite類中裂明,那么可以避免上述不安全問(wèn)題;但客戶端需要就要區(qū)分Leaf和Composite了。

(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闽晦,一起剝皮案震驚了整個(gè)濱河市扳碍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仙蛉,老刑警劉巖笋敞,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異荠瘪,居然都是意外死亡夯巷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門哀墓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)趁餐,“玉大人,你說(shuō)我怎么就攤上這事篮绰『罄祝” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵吠各,是天一觀的道長(zhǎng)臀突。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贾漏,這世上最難降的妖魔是什么候学? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮磕瓷,結(jié)果婚禮上盒齿,老公的妹妹穿的比我還像新娘。我一直安慰自己困食,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布翎承。 她就那樣靜靜地躺著硕盹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叨咖。 梳的紋絲不亂的頭發(fā)上瘩例,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音甸各,去河邊找鬼垛贤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趣倾,可吹牛的內(nèi)容都是我干的聘惦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼儒恋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼善绎!你這毒婦竟也來(lái)了黔漂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤禀酱,失蹤者是張志新(化名)和其女友劉穎炬守,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剂跟,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡减途,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了曹洽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片观蜗。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖衣洁,靈堂內(nèi)的尸體忽然破棺而出墓捻,到底是詐尸還是另有隱情,我是刑警寧澤坊夫,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布砖第,位于F島的核電站,受9級(jí)特大地震影響环凿,放射性物質(zhì)發(fā)生泄漏梧兼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一智听、第九天 我趴在偏房一處隱蔽的房頂上張望羽杰。 院中可真熱鬧,春花似錦到推、人聲如沸考赛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)颜骤。三九已至,卻和暖如春捣卤,著一層夾襖步出監(jiān)牢的瞬間忍抽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工董朝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸠项,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓子姜,卻偏偏與公主長(zhǎng)得像祟绊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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

  • 1 場(chǎng)景問(wèn)題# 1.1 商品類別樹## 考慮這樣一個(gè)實(shí)際的應(yīng)用:管理商品類別樹久免。 在實(shí)現(xiàn)跟商品有關(guān)的應(yīng)用系統(tǒng)的時(shí)候...
    七寸知架構(gòu)閱讀 6,015評(píng)論 10 59
  • 設(shè)計(jì)模式匯總 一浅辙、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,948評(píng)論 1 15
  • 1 場(chǎng)景問(wèn)題# 1.1 擴(kuò)展客戶管理的功能## 考慮這樣一個(gè)應(yīng)用:擴(kuò)展客戶管理的功能阎姥。 既然是擴(kuò)展功能记舆,那么肯定是...
    七寸知架構(gòu)閱讀 2,917評(píng)論 1 58
  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是組合模式 模式的結(jié)構(gòu) 典型代碼 代碼示例 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 模式應(yīng)用 一、...
    w1992wishes閱讀 890評(píng)論 0 2
  • 繼承是is-a的關(guān)系呼巴。組合和聚合有點(diǎn)像泽腮,有些書上沒(méi)有作區(qū)分,都稱之為has-a衣赶,有些書上對(duì)其進(jìn)行了較為嚴(yán)格區(qū)分诊赊,組...
    時(shí)待吾閱讀 460評(píng)論 0 1