java設(shè)計(jì)模式之Composite(組合)
內(nèi)容: Composite定義:將對(duì)象以樹形結(jié)構(gòu)組織起來,以達(dá)成“部分-整體 的層次結(jié)構(gòu),使得客戶端對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性.Composite比較容易理解,想到Composite就應(yīng)該想到樹形結(jié)構(gòu)圖。組合體內(nèi)這些對(duì)象都有共同接口,當(dāng)組合體一個(gè)對(duì)象的方法被調(diào)用執(zhí)行時(shí),Composite將遍歷(Iterator)整個(gè)樹形結(jié)構(gòu),尋找同樣包含這個(gè)方法的對(duì)象并實(shí)現(xiàn)調(diào)用執(zhí)行。可以用牽一動(dòng)百來形容。所以Composite模式使用到Iterator模式,和Chain of Responsibility模式類似。Composite好處:1.使客戶端調(diào)用簡(jiǎn)單,客戶端可以一致的使用組合結(jié)構(gòu)或其中單個(gè)對(duì)象,用戶就不必關(guān)系自己處理的是單個(gè)對(duì)象還是整個(gè)組合結(jié)構(gòu),這就簡(jiǎn)化了客戶端代碼。2.更容易在組合體內(nèi)加入對(duì)象部件. 客戶端不必因?yàn)榧尤肓诵碌膶?duì)象部件而更改代碼。如何使用Composite?首先定義一個(gè)接口或抽象類,這是設(shè)計(jì)模式通用方式了,其他設(shè)計(jì)模式對(duì)接口內(nèi)部定義限制不多,Composite卻有個(gè)規(guī)定,那就是要在接口內(nèi)部定義一個(gè)用于訪問和管理Composite組合體的對(duì)象們(或稱部件Component).下面的代碼是以抽象類定義,一般盡量用接口interface,;
public abstract class Equipment{private String name; //實(shí)價(jià)public abstract double netPrice();//折扣價(jià)格public abstract double discountPrice();//增加部件方法public boolean add(Equipment equipment) { return false; }//刪除部件方法public boolean remove(Equipment equipment) { return false; }//注意這里,這里就提供一種用于訪問組合體類的部件方法。public Iterator iter() { return null; }public Equipment(final String name) { this.name=name; }}抽象類Equipment就是Component定義,代表著組合體類的對(duì)象們,Equipment中定義幾個(gè)共同的方法。;
public class Disk extends Equipment{public Disk(String name) { super(name); }//定義Disk實(shí)價(jià)為1public double netPrice() { return 1.; }//定義了disk折扣價(jià)格是0.5 對(duì)折。public double discountPrice() { return .5; }}Disk是組合體內(nèi)的一個(gè)對(duì)象,或稱一個(gè)部件,這個(gè)部件是個(gè)單獨(dú)元素( Primitive)。還有一種可能是,一個(gè)部件也是一個(gè)組合體,就是說這個(gè)部件下面還有'兒子',這是樹形結(jié)構(gòu)中通常的情況,應(yīng)該比較容易理解。現(xiàn)在我們先要定義這個(gè)組合體:;
abstract class CompositeEquipment extends Equipment{private int i=0; //定義一個(gè)Vector 用來存放'兒子'private Lsit equipment=new ArrayList();public CompositeEquipment(String name) { super(name); }public boolean add(Equipment equipment) { this.equipment.add(equipment); return true; }public double netPrice() {double netPrice=0.;Iterator iter=equipment.iterator();for(iter.hasNext())netPrice+=((Equipment)iter.next()).netPrice();return netPrice;}public double discountPrice() {double discountPrice=0.;Iterator iter=equipment.iterator();for(iter.hasNext())discountPrice+=((Equipment)iter.next()).discountPrice();return discountPrice;}//注意這里,這里就提供用于訪問自己組合體內(nèi)的部件方法。//上面dIsk 之所以沒有,是因?yàn)镈isk是個(gè)單獨(dú)(Primitive)的元素.public Iterator iter(){return equipment.iterator() ;{//重載Iterator方法 public boolean hasNext() { return i//重載Iterator方法 public Object next() {if(hasNext()) return equipment.elementAt(i++);else throw new NoSuchElementException(); }}上面CompositeEquipment繼承了Equipment,同時(shí)為自己里面的對(duì)象們提供了外部訪問的方法,重載了Iterator,Iterator是Java的Collection的一個(gè)接口,是Iterator模式的實(shí)現(xiàn).我們?cè)倏纯碈ompositeEquipment的兩個(gè)具體類:盤盒Chassis和箱子Cabinet,箱子里面可以放很多東西,如底板,電源盒,硬盤盒等;盤盒里面可以放一些小設(shè)備,如硬盤 軟驅(qū)等。無疑這兩個(gè)都是屬于組合體性質(zhì)的。;
public class Chassis extends CompositeEquipment{ public Chassis(String name) { super(name); } public double netPrice() { return 1.+super.netPrice(); } public double discountPrice() { return .5+super.discountPrice(); }} public class Cabinet extends CompositeEquipment{ public Cabinet(String name) { super(name); } public double netPrice() { return 1.+super.netPrice(); } public double discountPrice() { return .5+super.discountPrice(); }}至此我們完成了整個(gè)Composite模式的架構(gòu)。我們可以看看客戶端調(diào)用Composote代碼:Cabinet cabinet=new Cabinet("Tower");Chassis chassis=new Chassis("PC Chassis");//將PC Chassis裝到Tower中 (將盤盒裝到箱子里)cabinet.add(chassis);//將一個(gè)10GB的硬盤裝到 PC Chassis (將硬盤裝到盤盒里)chassis.add(new Disk("10 GB"));//調(diào)用 netPrice()方法;System.out.println("netPrice="+cabinet.netPrice());System.out.println("discountPrice="+cabinet.discountPrice());上面調(diào)用的方法netPrice()或discountPrice(),實(shí)際上Composite使用Iterator遍歷了整個(gè)樹形結(jié)構(gòu),尋找同樣包含這個(gè)方法的對(duì)象并實(shí)現(xiàn)調(diào)用執(zhí)行.Composite是個(gè)很巧妙體現(xiàn)智慧的模式,在實(shí)際應(yīng)用中,如果碰到樹形結(jié)構(gòu),我們就可以嘗試是否可以使用這個(gè)模式。以論壇為例,一個(gè)版(forum)中有很多帖子(message),這些帖子有原始貼,有對(duì)原始貼的回應(yīng)貼,是個(gè)典型的樹形結(jié)構(gòu),那么當(dāng)然可以使用Composite模式,那么我們進(jìn)入Jive中看看,是如何實(shí)現(xiàn)的.Jive解剖在Jive中 ForumThread是ForumMessages的容器container(組合體).也就是說,F(xiàn)orumThread類似我們上例中的 CompositeEquipment.它和messages的關(guān)系如圖:[thread] |- [message] |- [message] |- [message] |- [message] |- [message] 我們?cè)贔orumThread看到如下代碼:;
public interface ForumThread { .... public void addMessage(ForumMessage parentMessage, ForumMessage newMessage) throws UnauthorizedException; public void deleteMessage(ForumMessage message) throws UnauthorizedException; public Iterator messages(); .... }類似CompositeEquipment, 提供用于訪問自己組合體內(nèi)的部件方法: 增加 刪除 遍歷.結(jié)合我的其他模式中對(duì)Jive的分析,我們已經(jīng)基本大體理解了Jive論壇體系的框架,如果你之前不理解設(shè)計(jì)模式,而直接去看Jive源代碼,你肯定無法看懂。:)Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
相關(guān)文章:
1. java設(shè)計(jì)模式之Interpreter2. java設(shè)計(jì)模式之Mediator3. PHP設(shè)計(jì)模式(七)組合模式Composite實(shí)例詳解【結(jié)構(gòu)型】4. java設(shè)計(jì)模式之Decorator5. java設(shè)計(jì)模式之Chain of Responsibility6. java設(shè)計(jì)模式之Template7. java設(shè)計(jì)模式之Visitor8. java設(shè)計(jì)模式之Bridge9. 詳解java設(shè)計(jì)模式之六大原則10. 實(shí)例講解JAVA設(shè)計(jì)模式之備忘錄模式
