組合模式

《大話設(shè)計(jì)模式》閱讀筆記和總結(jié)溅漾。原書是C#編寫的,本人用Java實(shí)現(xiàn)了一遍著榴,包括每種設(shè)計(jì)模式的UML圖實(shí)現(xiàn)和示例代碼實(shí)現(xiàn)添履。
目錄:設(shè)計(jì)模式
Github地址:DesignPattern

說明

定義:組合模式(Composite),將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)兄渺。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性缝龄。

UML圖:

組合模式UML圖.png

代碼實(shí)現(xiàn):

Component為組合中的對(duì)象聲明接口,在適當(dāng)情況下挂谍,實(shí)現(xiàn)所有類共有接口的默認(rèn)行為。聲明一個(gè)接口用于訪問和管理Component子部件

abstract class Component{
    protected String name;

    public Component(String name) {
        this.name = name;
    }
    
    public abstract void Add(Component c);
    public abstract void Remove(Component c);
    public abstract void Display(int depth);
    
}


Leaf在組合中表示葉節(jié)點(diǎn)對(duì)象瞎饲,葉節(jié)點(diǎn)沒有子節(jié)點(diǎn)

class Leaf extends Component{

    public Leaf(String name) {
        super(name);
    }

    @Override
    public void Add(Component c) {
        System.out.println("Cannot add to a leaf");
    }

    @Override
    public void Remove(Component c) {
        System.out.println("Cannot remove to a leaf");
    }

    /**
     * 頁節(jié)點(diǎn)的具體方法口叙,此處是顯示其名稱和級(jí)別
     * @param depth
     */
    @Override
    public void Display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
    }
}

Composite定義枝節(jié)點(diǎn)行為,用于存儲(chǔ)子部件嗅战,在Component接口中實(shí)現(xiàn)與子部件有關(guān)的操作妄田,比如增加Add和remove刪除

class Composite extends Component{
    
    private List<Component> children = new ArrayList<>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void Add(Component c) {
        children.add(c);
    }

    @Override
    public void Remove(Component c) {
        children.remove(c);
    }

    @Override
    public void Display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
        for (Component component : children) {
            component.Display(depth+2);
        }
    }
    
}

客戶端代碼

public class CompositePattern {
    public static void main(String[] args) {
        Composite root = new Composite("root");
        root.Add(new Leaf("Leaf A"));
        root.Add(new Leaf("Leaf B"));
        
        Composite comp = new Composite("Composite X");
        comp.Add(new Leaf("Leaf XA"));
        comp.Add(new Leaf("Leaf XB"));
        root.Add(comp);
        
        Composite comp2 = new Composite("Composite XY");
        comp2.Add(new Leaf("Leaf XYA"));
        comp2.Add(new Leaf("Leaf XYB"));
        comp.Add(comp2);
        
        root.Add(new Leaf("Leaf C"));
        
        Leaf leaf = new Leaf("Leaf D");
        root.Add(leaf);
        root.Remove(leaf);
        
        root.Display(1);
        
    }
}

運(yùn)行結(jié)果

-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
-----Composite XY
-------Leaf XYA
-------Leaf XYB
---Leaf C

示例

例子:一個(gè)公司的組織結(jié)構(gòu)圖如下圖所示,用程序來展示這個(gè)層級(jí)架構(gòu)驮捍。

組合模式示例圖.png

UML圖:

組合模式示例UML圖.png

代碼實(shí)現(xiàn):

公司類疟呐,抽象類或接口

public abstract class Company {
    protected String name;

    public Company(String name) {
        this.name = name;
    }
    
    public abstract void Add(Company c);//增加
    public abstract void Remove(Company c);//移除
    public abstract void Display(int depth);//顯示
    public abstract void LineOfDuty();//履行職責(zé)
}

具體公司類,實(shí)現(xiàn)接口樹枝節(jié)點(diǎn)

public class ConcreteCompany extends Company{
    
    private List<Company> children = new ArrayList<Company>();

    public ConcreteCompany(String name) {
        super(name);
    }

    @Override
    public void Add(Company c) {
        children.add(c);
    }

    @Override
    public void Remove(Company c) {
        children.remove(c);
    }

    @Override
    public void Display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
        
        for (Company company : children) {
            company.Display(depth+2);
        }
        
    }

    @Override
    public void LineOfDuty() {
        for (Company company : children) {
            company.LineOfDuty();
        }
    }

}

HR部門

public class HRDepartment extends Company{

    public HRDepartment(String name) {
        super(name);
    }

    @Override
    public void Add(Company c) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void Remove(Company c) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void Display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
        
    }

    @Override
    public void LineOfDuty() {
        System.out.println(name+"員工招聘培訓(xùn)管理");
        
    }

}

財(cái)務(wù)部

public class FinanceDepartment extends Company{

    public FinanceDepartment(String name) {
        super(name);
    }

    @Override
    public void Add(Company c) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void Remove(Company c) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void Display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
        
    }

    @Override
    public void LineOfDuty() {
        System.out.println(name+"公司財(cái)務(wù)收支管理");
        
    }

}

客戶端代碼

public class Main {
    public static void main(String[] args) {
        ConcreteCompany root = new ConcreteCompany("北京總公司");
        root.Add(new HRDepartment("總公司人力資源部"));
        root.Add(new HRDepartment("總公司財(cái)務(wù)部"));
    
        ConcreteCompany comp = new ConcreteCompany("上海華東分公司");
        comp.Add(new HRDepartment("上海華東分公司人力資源部"));
        comp.Add(new HRDepartment("上海華東分公司財(cái)務(wù)部"));
        root.Add(comp);
        
        ConcreteCompany comp1 = new ConcreteCompany("南京辦事處");
        comp1.Add(new HRDepartment("南京辦事處人力資源部"));
        comp1.Add(new HRDepartment("南京辦事處財(cái)務(wù)部"));
        comp.Add(comp1);
        
        ConcreteCompany comp2 = new ConcreteCompany("杭州辦事處");
        comp2.Add(new HRDepartment("杭州辦事處人力資源部"));
        comp2.Add(new HRDepartment("杭州辦事處財(cái)務(wù)部"));
        comp.Add(comp2);
        
        System.out.println("結(jié)構(gòu)圖");
        root.Display(1);
        
        System.out.println("職責(zé)");
        root.LineOfDuty();
    }
}

運(yùn)行結(jié)果

結(jié)構(gòu)圖
-北京總公司
---總公司人力資源部
---總公司財(cái)務(wù)部
---上海華東分公司
-----上海華東分公司人力資源部
-----上海華東分公司財(cái)務(wù)部
-----南京辦事處
-------南京辦事處人力資源部
-------南京辦事處財(cái)務(wù)部
-----杭州辦事處
-------杭州辦事處人力資源部
-------杭州辦事處財(cái)務(wù)部
職責(zé)
總公司人力資源部員工招聘培訓(xùn)管理
總公司財(cái)務(wù)部員工招聘培訓(xùn)管理
上海華東分公司人力資源部員工招聘培訓(xùn)管理
上海華東分公司財(cái)務(wù)部員工招聘培訓(xùn)管理
南京辦事處人力資源部員工招聘培訓(xùn)管理
南京辦事處財(cái)務(wù)部員工招聘培訓(xùn)管理
杭州辦事處人力資源部員工招聘培訓(xùn)管理
杭州辦事處財(cái)務(wù)部員工招聘培訓(xùn)管理
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末东且,一起剝皮案震驚了整個(gè)濱河市启具,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌珊泳,老刑警劉巖鲁冯,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拷沸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡薯演,警方通過查閱死者的電腦和手機(jī)撞芍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跨扮,“玉大人序无,你說我怎么就攤上這事『獯矗” “怎么了帝嗡?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)钧汹。 經(jīng)常有香客問我丈探,道長(zhǎng),這世上最難降的妖魔是什么拔莱? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任碗降,我火速辦了婚禮,結(jié)果婚禮上塘秦,老公的妹妹穿的比我還像新娘讼渊。我一直安慰自己,他們只是感情好尊剔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布爪幻。 她就那樣靜靜地躺著,像睡著了一般须误。 火紅的嫁衣襯著肌膚如雪挨稿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天京痢,我揣著相機(jī)與錄音奶甘,去河邊找鬼。 笑死祭椰,一個(gè)胖子當(dāng)著我的面吹牛臭家,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播方淤,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼钉赁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了携茂?” 一聲冷哼從身側(cè)響起你踩,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后姓蜂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體按厘,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年钱慢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了懒棉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡览绿,死狀恐怖策严,靈堂內(nèi)的尸體忽然破棺而出妻导,到底是詐尸還是另有隱情倔韭,我是刑警寧澤寿酌,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站秧荆,受9級(jí)特大地震影響辰如,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毙玻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一允睹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧该互,春花似錦宇智、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酿愧。三九已至,卻和暖如春庞钢,著一層夾襖步出監(jiān)牢的瞬間基括,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留魔眨,地道東北人侄刽。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蚁鳖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子醉箕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 1 場(chǎng)景問題# 1.1 商品類別樹## 考慮這樣一個(gè)實(shí)際的應(yīng)用:管理商品類別樹。 在實(shí)現(xiàn)跟商品有關(guān)的應(yīng)用系統(tǒng)的時(shí)候...
    七寸知架構(gòu)閱讀 6,014評(píng)論 10 59
  • 組合模式Composite 背景 我們可以使用簡(jiǎn)單的對(duì)象組合成復(fù)雜的對(duì)象损肛,而這個(gè)復(fù)雜對(duì)象有可以組合成更大的對(duì)象。我...
    踐行者閱讀 489評(píng)論 1 3
  • 【學(xué)習(xí)難度:★★★☆☆荣瑟,使用頻率:★★★★☆】直接出處:組合模式梳理和學(xué)習(xí):https://github.com/...
    BruceOuyang閱讀 994評(píng)論 0 1
  • 繼承是is-a的關(guān)系治拿。組合和聚合有點(diǎn)像劫谅,有些書上沒有作區(qū)分,都稱之為has-a嚷掠,有些書上對(duì)其進(jìn)行了較為嚴(yán)格區(qū)分,組...
    時(shí)待吾閱讀 459評(píng)論 0 1
  • 何為組合模式悲雳? 組合模式讓我們可以把相同基類型的對(duì)象組合到樹狀結(jié)構(gòu)中透典,其中父節(jié)點(diǎn)包含同類型的子節(jié)點(diǎn)峭咒。換句話說税弃,這種...
    泥孩兒0107閱讀 249評(píng)論 0 0