午夜拍鍵驚奇
          子夜 編程 代碼與我同在
          posts - 48,comments - 118,trackbacks - 79

          “策略模式”的出現(xiàn),是為了提供一套相互之間可靈活替換的算法,在不影響上層接口的情況下,用戶可以自由選擇不同的算法完成邏輯。

          策略模式的UML示意圖如下:?

          r_image002.jpg?

          ?其中算法的模型接口在“抽象策略”中定義,各具象策略實現(xiàn)不同的策略。“消費API”就是調(diào)用不同算法的類,在其內(nèi)部根據(jù)不同需要選擇不同的算法。有時需要將具象策略實例化后再傳給其它類,這時可以使用“簡單工廠”(Simple Factory“工廠方法”(Factory Method生成所需的具象策略。下面就以我正在做的一個項目,簡化一下后說明一下策略模式的使用。

          該項目是一個小型的商業(yè)網(wǎng)站,邏輯層由Servlet實現(xiàn)。用戶有一個需求,需要從數(shù)據(jù)庫調(diào)出商品信息后能夠?qū)τ涗洶疵Q(name)、規(guī)格(standard)、價格(price)和注冊日期(register date)進行排序。雖然可以考慮按不同的排序關(guān)鍵字使用不同的sql語句(即不同的order by)查詢數(shù)據(jù)庫。但這樣做的網(wǎng)絡(luò)數(shù)據(jù)流量太大,每次需要從數(shù)據(jù)庫完整地取回一個數(shù)據(jù)集(ResultSet),所以我選擇了將數(shù)據(jù)集一次取到客戶端的一個List中,然后在客戶端按不同的關(guān)鍵字對List進行排序。

          java.util.Collections類中有一個public static void sort(List list, Comparator comparator)的方法,可以按照不同的Comparator對象對list進行排序,它使用的是快速排序,所以效率非常高。而java.util.Comparator是一個接口:

          ?

          package?java.util;

          public?abstract?interface?Comparator?{
          ??boolean?equals(Object?
          object);

          ??
          int?compare(Object?object,?Object?object1);
          }


          ?

          其中和排序有關(guān)的是compare方法,它返回一個整數(shù),若第一個參數(shù)比第二個參數(shù)“大”,則返回一個正數(shù),若“小”則返回一個負數(shù),若“相等”則返回0,這里的“大”、“小”、“相等”是由compare方法具體實現(xiàn)定義的一種比較標(biāo)準(zhǔn)。由這個方法不禁想到C語言中qsort函數(shù)中使用的函數(shù)指針int *compare(*,*)JAVA中之所以沒有函數(shù)指針,就是用接口取代了(更詳細的介紹見《Effective Java》中第22條“用類和接口來代替函數(shù)指針”)。

          很明顯,Comparator接口就是我們的“抽象策略”,sort方法就是我們的“消費API”,而不同的“具象策略”就是我們從Comparator接口實現(xiàn)的根據(jù)不同關(guān)鍵字排序的類。

          整個排序模型的UML圖如下,其中為了作圖方便,我從Comparator繼承了一個接口ItemComparator,根據(jù)不同的關(guān)鍵字從ItemComparator接口泛化了NameComparator類,PriceComparator類,RegisterDateComparator類和StandardComparator類。實際運用中不需要這個接口,四個類可以直接從Comparator泛化。ItemBean是一個封裝了商品信息的beanList中存放的就是這些beanItemSortItemComparator以及四個具體類實現(xiàn)了“簡單工廠”模式,并封裝了sort方法。

          ?o_strategy.dfPackage.jpg?


          ??? 下面是具體的代碼(StandardComparator類的代碼與NameComparator類的代碼大同小異,在這里不列出):

          ?

          NameComparator類:

          ?

          package?com.lim.designpatterns.strategy;

          public?class?NameComparator?implements?ItemComparator{
          ??NameComparator()
          {}??//?將構(gòu)造器封裝,包外的類欲得到Comparator實例只能通過簡單工廠

          ??
          public?int?compare(Object?o1,Object?o2){
          ????String?name1
          =((ItemBean)o1).getName();
          ????String?name2
          =((ItemBean)o2).getName();

          ????
          return?name1.compareTo(name2);??//?調(diào)用String的CompareTo方法
          ??}

          }

          ?

          PriceComparator

          ?

          package?com.lim.designpatterns.strategy;

          public?class?PriceComparator?implements?ItemComparator{
          ??PriceComparator()
          {}

          ??
          public?int?compare(Object?o1,Object?o2){
          ????Double?price1
          =new?Double(((ItemBean)o1).getPrice());
          ????Double?price2
          =new?Double(((ItemBean)o2).getPrice());

          ????
          return?price1.compareTo(price2);??//?調(diào)用Double的CompareTo方法
          ??}

          }

          ?

          RegisterDateComparator

          ?

          package?com.lim.designpatterns.strategy;

          import?java.util.
          *;

          public?class?RegisterDateComparator?implements?ItemComparator{
          ??RegisterDateComparator()
          {}

          ??
          public?int?compare(Object?o1,Object?o2){
          ????Date?date1
          =((ItemBean)o1).getRegisterDate();
          ????Date?date2
          =((ItemBean)o2).getRegisterDate();

          ????
          return?date1.compareTo(date2);??//?調(diào)用Date的CompareTo方法
          ??}

          }

          ?

          ItemSort

          ?

          package?com.lim.designpatterns.strategy;

          import?java.util.
          *;

          public?class?ItemSort{
          ??
          public?static?List?sort(List?items,ItemComparator?c){
          ????Collections.sort(items,c);
          ????
          return?items;
          ??}


          ??
          public?static?final?ItemComparator?NAME=new?NameComparator();??//?簡單工廠

          ??
          public?static?final?ItemComparator?PRICE=new?PriceComparator();

          ??
          public?static?final?ItemComparator?STANDARD=new?StandardComparator();

          ??
          public?static?final?ItemComparator?REG_DATE=new?RegisterDateComparator();
          }

          ?

          TestItemSort

          ?

          package?com.lim.designpatterns.strategy;

          import?java.util.
          *;

          public?class?TestItemSort{
          ??
          public?static?void?main(String[]?args){
          ????List?items
          =new?ArrayList();
          ????
          //?向List添加條目

          ????items
          =ItemSort.sort(items,ItemSort.NAME);??//?按名稱排序

          ????items
          =ItemSort.sort(items,ItemSort.PRICE);??//?按價格排序

          ????items
          =ItemSort.sort(items,ItemSort.REG_DATE);??//?按注冊日期排序

          ????items
          =ItemSort.sort(items,ItemSort.STANDARD);??//?按規(guī)格排序
          ??}

          }
          posted on 2005-08-04 12:37 ^ Mustang ^ 閱讀(1246) 評論(2)  編輯  收藏 所屬分類: Design Patterns

          FeedBack:
          # re: 使用策略模式(strategy pattern)實現(xiàn)多關(guān)鍵字排序
          2005-08-06 08:31 | 一竿殘照.金棣 @ blogJava.net
          恩,delphi中的TStringList有同樣的結(jié)構(gòu),受教,謝謝  回復(fù)  更多評論
            
          # re: 使用策略模式(Strategy)實現(xiàn)多關(guān)鍵字排序
          2006-08-28 17:08 | zhl
          I got it!
          3ks!  回復(fù)  更多評論
            
          主站蜘蛛池模板: 蒙自县| 荥阳市| 海宁市| 九台市| 麟游县| 南陵县| 洛宁县| 旺苍县| 山东省| 敖汉旗| 荥经县| 克东县| 芷江| 宁德市| 天柱县| 金门县| 塔城市| 霍山县| 广州市| 宣武区| 天台县| 广水市| 阆中市| 嘉义市| 商洛市| 特克斯县| 揭东县| 五指山市| 永吉县| 通山县| 商城县| 温州市| 长海县| 绥滨县| 东乡族自治县| 武宁县| 福海县| 登封市| 涿州市| 鹤山市| 苍南县|