隨筆-8  評論-4  文章-0  trackbacks-0

          Design Pattern Practice

          1.序
          本文從一個簡單的多列排序的例子入手,由淺入深地講解Design Pattern(設計模式)的目的、分析和實踐。
          文中的例子用到Compositor Pattern和Decorator Pattern。
          同時,文中的例子也提供了一類問題(條件組合問題)的解決方案。

          2.問題的引入
          Design Pattern(設計模式)的目標是,把共通問題中的不變部分和變化部分分離出來。不變的部分,就構成了Design Pattern(設計模式)。這一點和Framework(框架)有些象。
          下面舉個排序的例子,說明如何抽取問題中的不變部分。
          假設一個Java類Record有field1,field2,field3等字段。


          public class Record{
          public int field1;
          public long field2;
          public double filed3;
          };


          我們還有一個Record對象的數組Record[] records。我們需要對這個數組按照不同的條件排序。
          首先,按照field1的大小從小到大進行升序排序。
          排序函數如下:


          void sort(Record[] records){
          for(int i =…){
          for(int j=…){
          if(records[ i ].field1 > records[ j ].field1)
          // swap records[ i ] and records[ j ]
          }
          }
          }


          其次,按照field2的大小從小到大進行升序排序。

          void sort(Record[] records){
          for(int i =…){
          for(int j=…){
          if(records[ i ].field2 > records[ j ].field2)
          // swap records[ i ] and records[ j ]
          }
          }
          }


          再次,按照field3的大小從小到大進行升序排序。
          ...
          這種要求太多了,我們寫了太多的重復代碼。我們可以看到,問題的變化部分,只有判斷條件部分(黑體的if條件判斷語句)。
          我們可以引入一個Comparator接口,把這個變化的部分抽取出來。

          public interface Comparator(){
          public boolean greaterThan(Record a, Record b);
          };


          sort函數就可以這樣寫(把判斷條件作為參數):


          void sort(Record[] records, Comparator compare){
          for(int i =….){
          for(int j=….){
          if(compare.greaterThen(records[ i ], records[ j ]))
          // swap records[ i ] and records[ j ]
          }
          }
          }


          這樣,對應第一個要求――對records數組按照field1的大小排序。
          我們可以做一個實現Comparator接口的CompareByField1類。


          public class CompareByField1 implements Comparator{
          public boolean greaterThan(Record a, Record b){
          if(a.filed1 > b.filed1){
          return ture;
          }
          return false;
          }
          }


          sort函數的調用為:

          sort(records, new CompareByField1());


          這樣,對應第一個要求――對records數組按照field2的大小排序。
          我們可以做一個實現Comparator接口的CompareByField2類。

          public class CompareByField2 implements Comparator{
          public boolean greaterThan(Record a, Record b){
          if(a.filed2 > b.filed2){
          return ture;
          }
          return false;
          }
          }
          [code]

          sort函數的調用為:
          [code]
          sort(records, new CompareByField2());


          按照C++ STL的叫法,這里的sort稱為算法(Algorithm),records稱為容器(集合),Comparator稱為函數對象(Function Object)。

          JDK的java.util.Collections類的sort方法和java.util.Comparator接口就是按照這樣的思路設計的。下面我們來看看如何應用sort和Comparator解決多列排序問題。

          buaawhl

          發表文章: 18
          注冊時間: 2004年07月06日 10:53
          Re: 這么多設計模式,我的看法和理解 發表: 2004年07月09日 18:37 回復
          3.多列排序問題

          3.1排序條件的數量

          我們知道,SQL語句能夠實現強大的排序功能,能夠按照不同字段的排列進行排序,也能夠按照升序,降序排序。比如下面的語句。
          order by field1 asc, field2 asc, field3 desc。

          這個排序條件按照field1的升序,field2的升序,field3的降序排序。
          注意,排在前面的字段具有較高的優先級。
          比如,兩條紀錄A和B,滿足如下條件:
          (1)A.field1 > B.field1,(2)A.field2 < B.field2。
          這時如果按照order by field1, field2語句排序,那么 A > B。
          如果上述條件中的(1)A.field1 > B.field1變化為A.field1 == B.field1。這時,條件(2)就會起作用。這時,A < B。

          我們來看看在Java中如何實現這種靈活而強大的排序。
          我們還是以上一節的Record類為例。Record類有3個字段,我們來看一看,有多少種可能的排序條件。
          (1)按field1排序。(2)按field2排序。(3)按field3排序。(4)按field1,field2排序。(5)按field1升序,按field2降序排序…...

          各種排序條件的排列組合,大概共有30種。而且,隨著字段個數的增長,排序條件的個數呈冪級數的增長。
          按照上一節的sort和Comparator方法,如果我們需要達到按照任意條件進行排序的目的,那么我們需要為每一個排序條件提供一個Comparator,我們需要30個Comparator類。:-)

          當然,我們不會這么做,我們能夠進一步提取這個問題中的相同重復部分,優化我們的解決方案。

          3.2 問題分析
          我們來分析這個問題中變化的部分和不變的部分。
          上面所有的排序條件中,不變的部分有3部分:
          (1)A.field1和B.field1的比較,
          (2)A.field2和B.field2的比較,
          (3)A.field3和B.field3的比較;

          變化的部分有兩部分,
          (1)這三種比較條件的任意組合排列,
          (2)升序和降序。

          根據這段分析,我們引入兩個類,ReverseComparator類和CompositeComparator類。
          CompositeComparator類用來解決字段的組合排列問題。
          ReverseComparator類用來解決字段的升序、降序問題。

          3.3 ReverseComparator類的代碼

          import java.util.Comparator;

          public class ReverseComparator implements Comparator{
          /** the original comparator*/
          private Comparator originalComparator = null;

          /** constructor takes a comparator as parameter */
          public ReverseComparator(Comparator comparator){
          originalComparator = comparator;
          }

          /** reverse the result of the original comparator */
          public int compare(Object o1, Object o2){
          return - originalComparator.compare(o1, o2);
          }
          }


          3.4 CompositeComparator類的代碼

          import java.util.Comparator;
          import java.util.Iterator;
          import java.util.List;
          import java.util.LinkedList;

          public class CompositeComparator implements Comparator{
          /** in the condition list, comparators' priority decrease from head to tail */
          private List comparators = new LinkedList();

          /** get the comparators, you can manipulate it as need.*/
          public List getComparators(){
          return comparators;
          }

          /** add a batch of comparators to the condition list */
          public void addComparators(Comparator[] comparatorArray){
          if(comparatorArray == null){
          return;
          }

          for(int i = 0; i < comparatorArray.length; i++){
          comparators.add(comparatorArray[i]);
          }
          }

          /** compare by the priority */
          public int compare(Object o1, Object o2){
          for(Iterator iterator = comparators.iterator(); iterator.hasNext();){
          Comparator comparator = (Comparator)iterator.next();

          int result = comparator.compare(o1, o2);

          if(result != 0){
          return result;
          }
          }

          return 0;
          }
          }


          3.5 Comparator的組合應用
          這一節講述上面兩個類的用法。
          對應前面的排序問題,我們只需要3個Comparator類:
          (1)Field1Comaprator;
          (2)Field2Comaprator;
          (3)Field3Comaprator。

          下面舉例說明,如何組合這些Comparator實現不同的排序條件。
          (1)order by field1, field2


          CompoiComparator myComparator = new CompoiComparator();
          myComparator. addComparators(
          new Comparator[]{
          new Field1Comaprator (), new Field2Comaprator ()};
          );

          // records is a list of Record
          Collections.sort(records, myComparator);

          (1)order by field1 desc, field2

          CompoiComparator myComparator = new CompoiComparator();
          myComparator. addComparators(
          new Comparator[]{
          new ReverseComparator(new Field1Comaprator ()),
          new Field2Comaprator ()};
          );

          // records is a list of Record
          Collections.sort(records, myComparator);



          這里提供的ReverseComparator類和CompositeComparator類都采用了Decorator Pattern。
          CompositeComparator類同時也是Composite Pattern。

          4.過濾條件的排列組合
          過濾條件問題也屬于條件組合問題的范疇。比如JDK提供的java.io.File類提供了一個文件過濾方法listFile(FileFilter),用戶可以定制不同的FileFilter,實現不同的過濾條件,比如文件時間在某個范圍內;文件后綴名,文件名符合某種模式;是目錄,還是文件,等等。
          同樣,我們可以應用上述的解決方法,實現靈活的過濾條件組合――用一個CompositeFilter類任意組合過濾條件,用一個ReverseFilter類作為排除條件。

          4.1 CompositeFilter類的代碼

          import java.io.FileFilter;
          import java.io.File;

          import java.util.Iterator;
          import java.util.List;
          import java.util.LinkedList;

          public class CompositeFilter implements FileFilter {

          /** in the filter list, every condition should be met. */
          private List filters = new LinkedList();

          /** get the filters, you can manipulate it as need.*/
          public List getFilters(){
          return filters;
          }

          /** add a batch of filters to the condition list */
          public void addComparators(FileFilter[] filterArray){
          if(filterArray == null){
          return;
          }

          for(int i = 0; i < filterArray.length; i++){
          filters.add(filterArray[i]);
          }
          }

          /** must meet all the filter condition */
          public boolean accept(File pathname) {
          for(Iterator iterator = filters.iterator(); iterator.hasNext();){
          FileFilter filter = (FileFilter)iterator.next();

          boolean result = filter.accept(pathname);

          // if any condition can not be met, return false.
          if(result == false){
          return false;
          }
          }

          // all conditions are met, return true.
          return true;
          }
          }


          4.2 ReverseFilter類的代碼


          import java.util.Comparator;

          public class ReverseComparator implements Comparator{
          /** the original comparator*/
          private Comparator originalComparator = null;

          /** constructor takes a comparator as parameter */
          public ReverseComparator(Comparator comparator){
          originalComparator = comparator;
          }

          /** reverse the result of the original comparator */
          public int compare(Object o1, Object o2){
          return - originalComparator.compare(o1, o2);
          }
          }

          posted on 2007-12-04 22:48 怡眾科技 閱讀(1320) 評論(1)  編輯  收藏 所屬分類: 轉載區

          評論:
          # re: 關于設計模式應用的意義 2008-05-13 15:10 | question
          你的排序好象達不到SQL按多列排序的效果????????  回復  更多評論
            
          主站蜘蛛池模板: 城市| 新竹县| 承德县| 安岳县| 门头沟区| 平安县| 老河口市| 开平市| 红安县| 河间市| 乾安县| 乐山市| 五河县| 河西区| 永城市| 台中县| 荃湾区| 专栏| 兰州市| 明光市| 开封县| 临夏县| 抚顺市| 开原市| 漾濞| 宜宾县| 北碚区| 峨眉山市| 临夏市| 昆明市| 牟定县| 大关县| 邹城市| 东阿县| 邵阳市| 大石桥市| 南川市| 开鲁县| 惠东县| 陈巴尔虎旗| 阿巴嘎旗|