小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

設(shè)計(jì)模式之Composite(組合)

 HaiLan 2006-09-14

設(shè)計(jì)模式之Composite(組合)

板橋里人 http://www. 2002/04/27(轉(zhuǎn)載請保留)

模式實(shí)戰(zhàn)書籍《Java實(shí)用系統(tǒng)開發(fā)指南》

Composite模式定義:
將對象以樹形結(jié)構(gòu)組織起來,以達(dá)成部分-整體的層次結(jié)構(gòu),使得客戶端對單個(gè)對象和組合對象的使用具有一致性.

Composite比較容易理解,想到Composite就應(yīng)該想到樹形結(jié)構(gòu)圖。組合體內(nèi)這些對象都有共同接口,當(dāng)組合體一個(gè)對象的方法被調(diào)用執(zhí)行時(shí),Composite將遍歷(Iterator)整個(gè)樹形結(jié)構(gòu),尋找同樣包含這個(gè)方法的對象并實(shí)現(xiàn)調(diào)用執(zhí)行。可以用牽一動(dòng)百來形容。

所以Composite模式使用到Iterator模式,和Chain of Responsibility模式類似。

Composite好處:
1.
使客戶端調(diào)用簡單,客戶端可以一致的使用組合結(jié)構(gòu)或其中單個(gè)對象,用戶就不必關(guān)系自己處理的是單個(gè)對象還是整個(gè)組合結(jié)構(gòu),這就簡化了客戶端代碼。
2.
更容易在組合體內(nèi)加入對象部件. 客戶端不必因?yàn)榧尤肓诵碌膶ο蟛考拇a。

如何使用Composite?
首先定義一個(gè)接口或抽象類,這是設(shè)計(jì)模式通用方式了,其他設(shè)計(jì)模式對接口內(nèi)部定義限制不多,Composite卻有個(gè)規(guī)定,那就是要在接口內(nèi)部定義一個(gè)用于訪問和管理Composite組合體的對象們(或稱部件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定義,代表著組合體類的對象們,Equipment中定義幾個(gè)共同的方法。

public class Disk extends Equipment
{
  public Disk(String name) { super(name); }
  //定義Disk實(shí)價(jià)為1
  public double netPrice() { return 1.; }
  //定義了disk折扣價(jià)格是0.5 對折。
  public double discountPrice() { return .5; }
}

Disk是組合體內(nèi)的一個(gè)對象,或稱一個(gè)部件,這個(gè)部件是個(gè)單獨(dú)元素( Primitive)。
還有一種可能是,一個(gè)部件也是一個(gè)組合體,就是說這個(gè)部件下面還有兒子,這是樹形結(jié)構(gòu)中通常的情況,應(yīng)該比較容易理解?,F(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)?span lang=EN-US>Disk
是個(gè)單獨(dú)(Primitive)的元素.
  public Iterator iter()
  {
    return equipment.iterator() ;
  {
  //重載Iterator方法
   public boolean hasNext() { return i<equipment.size(); }
  //重載Iterator方法
   public Object next()
   {
    if(hasNext())
       return equipment.elementAt(i++);
    else
        throw new NoSuchElementException();
   }
  

}

上面CompositeEquipment繼承了Equipment,同時(shí)為自己里面的對象們提供了外部訪問的方法,重載了Iterator,IteratorJavaCollection的一個(gè)接口,是Iterator模式的實(shí)現(xiàn).

我們再看看CompositeEquipment的兩個(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è)方法的對象并實(shí)現(xiàn)調(diào)用執(zhí)行.

Composite是個(gè)很巧妙體現(xiàn)智慧的模式,在實(shí)際應(yīng)用中,如果碰到樹形結(jié)構(gòu),我們就可以嘗試是否可以使用這個(gè)模式。

以論壇為例,一個(gè)版(forum)中有很多帖子(message),這些帖子有原始貼,有對原始貼的回應(yīng)貼,是個(gè)典型的樹形結(jié)構(gòu),那么當(dāng)然可以使用Composite模式,那么我們進(jìn)入Jive中看看,是如何實(shí)現(xiàn)的.

Jive解剖
Jive ForumThreadForumMessages的容器container(組合體).也就是說,ForumThread類似我們上例中的 CompositeEquipment.它和messages的關(guān)系如圖:
[thread]
   |- [message]
   |- [message]
      |- [message]
      |- [message]
         |- [message]

我們在ForumThread看到如下代碼:

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é)合我的其他模式中對Jive的分析,我們已經(jīng)基本大體理解了Jive論壇體系的框架,如果你之前不理解設(shè)計(jì)模式,而直接去看Jive源代碼,你肯定無法看懂。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多