熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

java設計模式之 Composite(組合)

2022-06-13   來源: Java高級技術 

  Composite定義:
  將對象以樹形結構組織起來以達成部分-整體 的層次結構使得客戶端對單個對象和組合對象的使用具有一致性
  
  Composite比較容易理解想到Composite就應該想到樹形結構圖組合體內這些對象都有共同接口當組合體一個對象的方法被調用執行時Composite將遍歷(Iterator)整個樹形結構尋找同樣包含這個方法的對象並實現調用執行可以用牽一動百來形容
  
  所以Composite模式使用到Iterator模式和Chain of Responsibility模式類似
  
  Composite好處:
  使客戶端調用簡單客戶端可以一致的使用組合結構或其中單個對象用戶就不必關系自己處理的是單個對象還是整個組合結構這就簡化了客戶端代碼
  更容易在組合體內加入對象部件 客戶端不必因為加入了新的對象部件而更改代碼
  
  如何使用Composite?
  首先定義一個接口或抽象類這是設計模式通用方式了其他設計模式對接口內部定義限制不多Composite卻有個規定那就是要在接口內部定義一個用於訪問和管理Composite組合體的對象們(或稱部件Component)
  
  下面的代碼是以抽象類定義一般盡量用接口interface
  
  public abstract class Equipment
  {
    private String name;
    //實價
    public abstract double netPrice();
    //折扣價格
    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) { thisname=name; }
  } 
  
  抽象類Equipment就是Component定義代表著組合體類的對象們Equipment中定義幾個共同的方法
  
  public class Disk extends Equipment
  {
    public Disk(String name) { super(name); }
    //定義Disk實價為
    public double netPrice() { return ; }
    //定義了disk折扣價格是 對折
    public double discountPrice() { return ; }
  } 
  
  Disk是組合體內的一個對象或稱一個部件這個部件是個單獨元素( Primitive)
  還有一種可能是一個部件也是一個組合體就是說這個部件下面還有兒子這是樹形結構中通常的情況應該比較容易理解現在我們先要定義這個組合體
  
  abstract class CompositeEquipment extends Equipment
  {
    private int i=;
    //定義一個Vector 用來存放兒子
    private Lsit equipment=new ArrayList();
  
    public CompositeEquipment(String name) { super(name); }
  
    public boolean add(Equipment equipment) {
       thisequipmentadd(equipment);
       return true;
     }
  
    public double netPrice()
    {
      double netPrice=;
      Iterator iter=erator();
      for(iterhasNext())
        netPrice+=((Equipment)iternext()Price();
      return netPrice;
    }
  
    public double discountPrice()
    {
      double discountPrice=;
      Iterator iter=erator();
      for(iterhasNext())
        discountPrice+=((Equipment)iternext())discountPrice();
      return discountPrice;
    }
    
    //注意這裡這裡就提供用於訪問自己組合體內的部件方法
    //上面dIsk 之所以沒有是因為Disk是個單獨(Primitive)的元素
    public Iterator iter()
    {
      return erator()
    {
    //重載Iterator方法
     public boolean hasNext() { return i<equipmentsize(); }
    //重載Iterator方法
     public Object next()
     {
      if(hasNext())
         return equipmentelementAt(i++);
      else
          throw new NoSuchElementException();
     }
    
  }
  
  上面CompositeEquipment繼承了Equipment同時為自己裡面的對象們提供了外部訪問的方法重載了IteratorIterator是Java的Collection的一個接口是Iterator模式的實現
  
  我們再看看CompositeEquipment的兩個具體類:盤盒Chassis和箱子Cabinet箱子裡面可以放很多東西如底板電源盒硬盤盒等盤盒裡面可以放一些小設備如硬盤 軟驅等無疑這兩個都是屬於組合體性質的
  
  public class Chassis extends CompositeEquipment
  {
     public Chassis(String name) { super(name); }
     public double netPrice() { return +Price(); }
     public double discountPrice() { return +superdiscountPrice(); }
  }
  public class Cabinet extends CompositeEquipment
  {
     public Cabinet(String name) { super(name); }
     public double netPrice() { return +Price(); }
     public double discountPrice() { return +superdiscountPrice(); }
  }
  
  至此我們完成了整個Composite模式的架構
  
  我們可以看看客戶端調用Composote代碼:
  
  Cabinet cabinet=new Cabinet(Tower);
  
  Chassis chassis=new Chassis(PC Chassis);
  //將PC Chassis裝到Tower中 (將盤盒裝到箱子裡)
  cabinetadd(chassis);
  //將一個GB的硬盤裝到 PC Chassis (將硬盤裝到盤盒裡)
  chassisadd(new Disk( GB));
  
  //調用 netPrice()方法;
  Systemoutprintln(netPrice=+Price());
  Systemoutprintln(discountPrice=+cabinetdiscountPrice());
  
  上面調用的方法netPrice()或discountPrice()實際上Composite使用Iterator遍歷了整個樹形結構尋找同樣包含這個方法的對象並實現調用執行
  
  Composite是個很巧妙體現智慧的模式在實際應用中如果碰到樹形結構我們就可以嘗試是否可以使用這個模式
  
  以論壇為例一個版(forum)中有很多帖子(message)這些帖子有原始貼有對原始貼的回應貼是個典型的樹形結構那麼當然可以使用Composite模式那麼我們進入Jive中看看是如何實現的
  
  Jive解剖
  在Jive中 ForumThread是ForumMessages的容器container(組合體)也就是說ForumThread類似我們上例中的 CompositeEquipment它和messages的關系如圖
  [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 提供用於訪問自己組合體內的部件方法: 增加 刪除 遍歷
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27583.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.