設計模式之Composite(組合)

composite是將多個不一樣的而有着共同屬性需求的類組合到一塊,例如:購物車裏的全部商品都要有購物車所關心的屬性:價格,這些商品都會被交由compisite處理(一個購物車composite,多種商品要實現購物車/composite所須要的接口)
Composite模式定義:(貨架上的全部商品,購物車)        將對象以樹形結構組織起來,以達成「部分-總體」 的層次結構,使得客戶端對單個對象和組合對象的使用具備一致性. Composite比較容易理解,想到Composite就應該想到樹形結構圖。組合體內這些對象都有共同接口,當組合體一個對象的方 法被調用執行時,Composite將遍歷(Iterator)整個樹形結構,尋找一樣包含這個方法的對象並實現調用執行。能夠用牽一動百來形容。 因此Composite模式使用到Iterator模式,和Chain of Responsibility模式相似。 Composite好處:        1.使客戶端調用簡單,客戶端能夠一致的使用組合結構或其中單個對象,用戶就沒必要關係本身處理的是單個對象仍是整個組合結構,這就簡化了客戶端代碼。        2.更容易在組合體內加入對象部件. 客戶端沒必要由於加入了新的對象部件而更改代碼。 如何使用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) { this.name=name; }            } 抽象類Equipment就是Component定義,表明着組合體類的對象們,Equipment中定義幾個共同的方法。 public class Disk extends Equipment            {              public Disk(String name) { super(name); }                          //定義Disk實價爲1              public double netPrice() { return 1.; }              //定義了disk折扣價格是0.5 對摺。              public double discountPrice() { return .5; }            } Disk是組合體內的一個對象,或稱一個部件,這個部件是個單獨元素( Primitive)。        還有一種多是,一個部件也是一個組合體,就是說這個部件下面還有'兒子',這是樹形結構中一般的狀況,應該比較容易理解。如今咱們先要定義這個組合體: abstract class CompositeEquipment extends Equipment              {                private int i=0;                //定義一個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;                }                               //注意這裏,這裏就提供用於訪問本身組合體內的部件方法。                //上面dIsk 之因此沒有,是由於Disk是個單獨(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,同時爲本身裏面的對象們提供了外部訪問的方法,重載了Iterator,Iterator是Java的Collection的一個接口,是Iterator模式的實現. 咱們再看看CompositeEquipment的兩個具體類:盤盒Chassis和箱子Cabinet,箱子裏面能夠放不少東西,如底板,電源盒,硬盤盒等;盤盒裏面能夠放一些小設備,如硬盤        軟驅等。無疑這兩個都是屬於組合體性質的。 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();              }              } 至此咱們完成了整個Composite模式的架構。 咱們能夠看看客戶端調用Composote代碼:                Cabinet cabinet=new Cabinet("Tower");                Chassis chassis=new Chassis("PC Chassis");        //將PC Chassis裝到Tower中 (將盤盒裝到箱子裏)        cabinet.add(chassis);        //將一個10GB的硬盤裝到 PC Chassis (將硬盤裝到盤盒裏)        chassis.add(new Disk("10 GB"));                //調用 netPrice()方法;        System.out.println("netPrice="+cabinet.netPrice());        System.out.println("discountPrice="+cabinet.discountPrice());               上面調用的方法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, 提供用於訪問本身組合體內的部件方法: 增長 刪除 遍歷. 結合個人其餘模式中對Jive的分析,咱們已經基本大致理解了Jive論壇體系的框架,若是你以前不理解設計模式,而直接去看Jive源代碼,你確定沒法看懂。
相關文章
相關標籤/搜索