国产探花免费观看_亚洲丰满少妇自慰呻吟_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. }



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿图什市| 黄石市| 曲麻莱县| 苍梧县| 桐城市| 霍州市| 荣昌县| 南川市| 伊金霍洛旗| 宜丰县| 丘北县| 广安市| 麦盖提县| 苍溪县| 郯城县| 宁晋县| 临城县| 宁安市| 定结县| 盱眙县| 聂荣县| 抚宁县| 惠东县| 安福县| 饶平县| 巴青县| 德庆县| 监利县| 广灵县| 和静县| 柞水县| 义马市| 三门峡市| 柳林县| 四平市| 富蕴县| 唐山市| 资阳市| 鲁甸县| 江达县| 伊春市|