国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

在組合模式中實現訪問者(Visitor)模式

2019-11-18 12:16:11
字體:
來源:轉載
供稿:網友

   本文從一個給定的實現了組合(Composite)模式的例子開始,說明怎么在這個數據結構上實現業務邏輯代碼。依次介紹了非面向對象的方式、在組合結構中加入方法、使用訪問者(Visitor)模式以及用改進后的訪問者(Visitor)模式來實現相同的業務邏輯代碼,并且對于每種實現分別給出了優缺點。

  讀者定位于具有java程序開發和設計模式經驗的開發人員。

  讀者通過本文可以學到如何在組合(Composite)模式中實現各種不同的業務方法及其優缺點。

  組合(Composite)模式

  組合模式是結構型模式中的一種。GOF的《設計模式》一書中對使用組合模式的意圖描述如下:將對象組合成樹形結構以表示"部分-整體"的層次結構。Composite使得用戶對單個對象和組合對象的使用具有一致性。

  組合模式應用廣泛。根據GOF中對組合模式的定義,Composite模式一般由Component接口、Leaf類和Composite類組成。現在需要對一個軟件產品治理系統的實體建模:某公司開發了一系列軟件集(SoftwareSet),包含了多種品牌(Brand)的軟件產品,就象IBM提供了Lotus、WebsPhere等品牌。每個品牌下面又有各種產品(PRodUCt),如IBM的Lotus下面有Domino Server/Client產品等。建模后的類圖如下(代碼可以參見隨本文帶的附件中,包com.test.entity下所有的源文件):

在組合模式中實現訪問者(Visitor)模式(圖一)


  如圖所示:

  (1)接口SoftwareComponent就是對應于組合模式中的Component接口,它定義了所有類共有接口的缺省行為

  (2)AbsSoftwareComposite類對應于Composite類,并且是抽象類,所有可以包含子節點的類都擴展這個類。這個類的主要功能是用來存儲子部件,實現了接口中的方法,部分可以重用的代碼寫在此類中

  (3)SoftwareSet類繼續于AbsSoftwareComposite類,對應于軟件集,軟件集下直接可以包含品牌(Brand),也可以直接包含不屬于任何品牌的產品(Product)

  (4)Brand類繼續于AbsSoftwareComposite類,對應于品牌,包含了品牌名屬性,并且用來存儲Product類的實例

  (5)Product類就是對應的Leaf類,表示葉子節點,葉子節點沒有子節點

  用不同的方法實現業務邏輯

  數據結構建立好之后,需要在這個數據結構上添加方法實現業務邏輯。比如現在的這個例子中,有這樣的需求:給定一些用戶選擇好的產品,需要計算出這些選中后軟件的總價格。下面開始介紹如何使用各種不同的方法來實現這個業務邏輯。

  非面向對象的編程方式

  這種方式下,編程思路最簡單:遍歷SoftwareSet實例中的所有節點,假如遍歷到的當前對象是Product的話就累加,否則繼續遍歷下一層直到全部遍歷完畢。代碼片斷如下:

  1. /**
  2.  * 取得某個SoftwareComponent對象下面所有Product的價格
  3.  * @param brand
  4.  * @return
  5.  */
  6. public double getTotalPrice(SoftwareComponent softwareComponent) {
  7.     SoftwareComponent temp = softwareComponent;
  8.     double totalPrice = 0;
  9.     //假如傳入的實例是SoftwareSet的類型
  10.     if (temp instanceof SoftwareSet) {
  11.         Iterator it = ((SoftwareSet) softwareComponent).getChilds()
  12.                 .iterator();
  13.         while (it.hasNext()) {//遍歷
  14.             temp = (SoftwareComponent) it.next();
  15.             //假如子對象是Product類型的,直接累加
  16.             if (temp instanceof Product) {
  17.                 Product product = (Product) temp;
  18.                 totalPrice += product.getPrice();
  19.             } else if (temp instanceof Brand) { 
  20.             //假如子對象是Brand類型的,則遍歷Brand下面所有的產品并累加
  21.                 Brand brand = (Brand) temp;
  22.                 totalPrice += getBrandPrice(brand);
  23.             }
  24.         }
  25.     } else if (temp instanceof Brand) {
  26.         //假如傳入的實例是SoftwareSet的類型,則遍歷Brand下面所有的產品并累加
  27.         totalPrice += getBrandPrice((Brand) temp);
  28.     } else if (temp instanceof Product) {
  29.         //假如子對象是Product類型的,直接返回價格
  30.         return ((Product) temp).getPrice();
  31.     }
  32.     return totalPrice;
  33. }
  34. /**
  35.  * 取得某個Brand對象下面所有Product的價格
  36.  * @param brand
  37.  * @return
  38.  */
  39. private double getBrandPrice(Brand brand) {
  40.     Iterator brandIt = brand.getChilds().iterator();
  41.     double totalPrice = 0;
  42.     while (brandIt.hasNext()) {
  43.         Product product = (Product) brandIt.next();
  44.         totalPrice += product.getPrice();
  45.     }
  46.     return totalPrice;
  47. }



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 射阳县| 故城县| 中西区| 县级市| 海口市| 安远县| 姚安县| 大连市| 格尔木市| 老河口市| 延庆县| 寿宁县| 卢氏县| 商城县| 民县| 肇庆市| 威海市| 彩票| 上林县| 宿松县| 博湖县| 册亨县| 梨树县| 阳江市| 龙胜| 太和县| 勐海县| 丰顺县| 东明县| 海盐县| 蕲春县| 大关县| 佛学| 师宗县| 广汉市| 商丘市| 广元市| 遵义市| 澄城县| 屯留县| 松阳县|