1. 程式人生 > >推薦一個學習設計模式的地方及其合成模式的介紹

推薦一個學習設計模式的地方及其合成模式的介紹

合成模式

合成模式把部分和整體關係用樹結構表示,是屬於物件的結構模式。合成模式要對組合的物件進行管理,所以在一定位置給予物件的相關管理方法,如: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("旺旺", 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]元 名稱        價格 旺旺        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("旺旺", 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())時,在編譯期不會有錯,但在執行期會報錯,這樣不容易被發覺錯誤出在哪. 作者:飛行魚 QQ:6868861 推薦J2EE群:7715552