《Java設計模式》之合成模式

來源:互聯網
上載者:User

標籤:

合成模式合成模式把部分和整體關係用樹結構表示,是屬於對象的結構模式。合成模式要對組合的對象進行管理,所以在一定位置給予對象的相關管理方法,如:add(),remove()等.合成模式中對象的管理有兩種方案。1.安全方式:此方式只允許樹枝構件有對象的管理方法。2.透明方式:此方式只允許樹枝和樹葉都有對象的管理方法,但樹葉對象中的管理方法無實際意義。 一.UML 二.組成部分抽象構件:抽象組合對象的公用行為介面樹葉構件:樹葉對象,沒有下級子物件樹枝構件:樹枝對象,樹枝對象可以包含一個或多個其他樹枝或樹葉對象 三.代碼例子:我以一個超市購物為例(一)、安全方式1. 抽象物品(抽象構件)
package com.eekq.structure.composite.security;/* * 抽象構件,物品 * */public interface IRes {    /**購物買單,示意性的商業方法*/    public void pay();}


2. 單一物品(樹葉構件)
package com.eekq.structure.composite.security;public class SingleResImpl implements IRes {    /**物品名稱*/    private String name;    /**價錢*/    private float money;    public SingleResImpl(String name, float money) {        this.name = name;        this.money = money;    }    public void pay() {        System.out.println("購買了一件物品["+getName()+"],價錢是[" + getMoney()+"]元");    }    public float getMoney() {        // TODO 自動產生方法存根        returnthis.money;    }    public String getName() {        // TODO 自動產生方法存根        return this.name;    }      /**重寫equals*/    public boolean equals(Object obj){        SingleResImpl res = (SingleResImpl)obj;            return res.getName().equals(getName()) && res.getMoney()==getMoney();    }}


3. 多個物品(樹枝構件)
package com.eekq.structure.composite.security;import java.util.Iterator;import java.util.Vector;/* * 對多個物品的管理 * */public class MultiResImpl implements IRes {    /**購物車*/    private Vector car = new Vector();    private static float totle = 0.0f;     public void pay() {        if(!car.isEmpty()){        System.out.println("名稱        價格\n");        shopping();        System.out.println("\n總價:" + totle + "元");        }else{            System.out.println("您好,你沒有購買任何物品,不用買單!");               }    }    public void shopping() {              if (car != null || !car.isEmpty()) {            Iterator it = car.iterator();            SingleResImpl res = null;            Object temp = null;// 臨時對象            while (it.hasNext()) {                temp = it.next();                if (temp instanceof MultiResImpl) {                    ((MultiResImpl) temp).shopping();                } else {                    res = (SingleResImpl) temp;                    synchronized (this) {                        totle += res.getMoney();                    }                    System.out.println(res.getName() + "            " + res.getMoney()                            + "元");                }            }        }    }    /**加入新的物品*/    public void addRes(IRes res) {        car.add(res);    }     /**放回物品*/    public void removeRes(IRes res) {        car.remove(res);    } } 


4. 收銀台買單
package com.eekq.structure.composite.security;public class Main {    /**     *@paramargs     */    public static void main(String[] args) {        /**買支雪糕*/        IRes singleRes = new SingleResImpl("雪糕", 1.5f);        /**買單*/        singleRes.pay();         /**快過年了,我推了個購物車,多買點東西*/        IRes allRes = new MultiResImpl();                      /**在一樓買的食物*/        IRes one = new MultiResImpl();        ((MultiResImpl) allRes).addRes(one);//把一樓的東西裝在購物車裡        /**因為是安全方式的組合模式,因此不夠透明,只能明確的向下轉型,然後再加入購物車了*/        ((MultiResImpl) one).addRes(new SingleResImpl("WangWang", 28.5f));        ((MultiResImpl) one).addRes(new SingleResImpl("糖果", 38.0f));        ((MultiResImpl) one).addRes(new SingleResImpl("可樂", 8.5f));         /**二樓去買的衣服和襪子*/        IRes two = new MultiResImpl();        ((MultiResImpl) allRes).addRes(two);// 把二樓的東西裝也裝在購物車裡        ((MultiResImpl) two).addRes(new SingleResImpl("衣服", 130.5f));        ((MultiResImpl) two).addRes(new SingleResImpl("襪子", 10f));               /**二樓再買了個手錶,我放在bao裡*/        IRes bao = new MultiResImpl();        ((MultiResImpl) two).addRes(bao);//把購物小封裝在二樓購物車裡        ((MultiResImpl) bao).addRes(new SingleResImpl("手錶", 100f));               /**回到一樓,又買了蘋果和梨*/        ((MultiResImpl) one).addRes(new SingleResImpl("蘋果", 10.0f));        ((MultiResImpl) one).addRes(new SingleResImpl("梨", 3.0f));/**在買單之前我把可樂退了,因為家裡還有的嘛*/        ((MultiResImpl) one).removeRes(new SingleResImpl("可樂", 8.5f));        /**在收銀台一次性對購物車所有物品買單*/        allRes.pay();    }}


 5. 運行結果購買了一件物品[雪糕],價錢是[1.5]元名稱        價格 WangWang        28.5元糖果        38.0元蘋果        10.0元梨          3.0元衣服        130.5元襪子        10.0元手錶        100.0元 總價:320.0元 (二)、透明方式透明方式與安全方式的不同點在於抽象構件,透明方式使用的是統一介面。1.  抽象構件
package com.eekq.structure.composite.clarity; /* * 抽象構件,物品 * */public interface IRes {    /**購物買單,示意性的商業方法*/    public void pay();     /**加入新的物品*/    public void addRes(IRes res);     /**放回物品*/    public void removeRes(IRes res);}


2.  單一物品(樹葉構件)
package com.eekq.structure.composite.security; public class SingleResImpl implements IRes {     /**物品名稱*/    private String name;     /**價錢*/    private float money;     public SingleResImpl(String name, float money) {        this.name = name;        this.money = money;    }     public void pay() {        System.out.println("購買了一件物品["+getName()+"],價錢是[" + getMoney()+"]元");    }     public float getMoney() {        // TODO 自動產生方法存根        return this.money;    }     public String getName() {        // TODO 自動產生方法存根        return this.name;    }       /**重寫equals*/    public boolean equals(Object obj){        SingleResImpl res = (SingleResImpl)obj;            return res.getName().equals(getName()) && res.getMoney()==getMoney();    } }


3. 多個物品(樹枝構件) 同安全模式代碼一樣!4. 收銀台買單 
package com.eekq.structure.composite.clarity;public class Main {    /**     *@paramargs     */    public static void main(String[] args) {        /**買支雪糕*/        IRes singleRes = new SingleResImpl("雪糕", 1.5f);        /**買單*/        singleRes.pay();        /**快過年了,我推了個購物車,多買點東西*/        IRes allRes = new MultiResImpl();         /**在一樓買的食物*/        IRes one = new MultiResImpl();        allRes.addRes(one);// 把一樓的東西裝在購物車裡        /**因為是透明方式的組合模式,因此直接調用就是了*/        one.addRes(new SingleResImpl("WangWang", 28.5f));        one.addRes(new SingleResImpl("糖果", 38.0f));        one.addRes(new SingleResImpl("可樂", 8.5f));         /**二樓去買的衣服和襪子*/        IRes two = new MultiResImpl();        allRes.addRes(two);// 把二樓的東西裝也裝在購物車裡        two.addRes(new SingleResImpl("衣服", 130.5f));        two.addRes(new SingleResImpl("襪子", 10f));        /**二樓再買了個手錶,我放在bao裡*/        IRes bao = new MultiResImpl();        two.addRes(bao);// 把購物小封裝在二樓購物車裡        bao.addRes(new SingleResImpl("手錶", 100f));        /**回到一樓,又買了蘋果和梨*/        one.addRes(new SingleResImpl("蘋果", 10.0f));        one.addRes(new SingleResImpl("梨", 3.0f));        /**在買單之前我把可樂退了,因為家裡還有的嘛*/        one.removeRes(new SingleResImpl("可樂", 8.5f));        /**在收銀台一次性對購物車所有物品買單*/        allRes.pay();    }}


5. 運行結果 同安全模式一樣的結果!四.總結合成模式是對象的結構模式,以上示範合成模式。在以後的項目中,如果遇到對象組合的情況,即也符合樹結構的。可以考慮下此模式。此模式中講述了安全方式和透明方式。安全方式:抽象構件上只提供樹葉和樹枝公用的方法,沒提供樹枝專屬的管理等方法(add(),remove())。這樣的好處是安全,使用者不會在樹葉上使用add()等管理方法,缺點是不夠透明,使用者必須知識當前對象為樹葉還是樹枝(向下轉型)。透明方式:抽象構件上提供了滿足樹枝的所有方法(包括add(),remove()),這樣做的好處是,使用者可以任意執行對象的add()和remove()管理對象。缺點是如果使用者在樹葉上執行管理方式(add(),remove())時,在編譯期不會有錯,但在執行期會報錯,這樣不容易被發覺錯誤出在哪.
如果以上內容不明白,推薦部落格地址:http://lavasoft.blog.51cto.com/62575/90824/

下面的資料來源:Steven John Metsker   和william C. wake 著 的  java設計模式(第二版)第五章內容:僅供大家參考和學習!












著作權聲明:歡迎轉載,希望在你轉載的同時,添加原文地址,謝謝配合

《Java設計模式》之合成模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.