<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    很久很久以前

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      34 隨筆 :: 4 文章 :: 17 評論 :: 0 Trackbacks

    http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=125&threadID=27195
    Design Pattern Practice
    1.序
    本文從一個簡單的多列排序的例子入手,由淺入深地講解Design Pattern(設計模式)的目的、分析和實踐。
    文中的例子用到Compositor Pattern和Decorator Pattern。
    同時,文中的例子也提供了一類問題(條件組合問題)的解決方案。

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


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





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


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





    其次,按照field2的大小從小到大進行升序排序。
    java代碼:?


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





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


    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,?records[j]))?
    ????????????????????????????????
    //?swap?records?and?records[j]?
    ????????????????}
    ?
    ????????}
    ?
    }
    ?





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


    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類。

    java代碼:?


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




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

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

    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類的代碼

    java代碼:?


    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類的代碼

    java代碼:?


    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);?
    ????}
    ?
    ??}
    ?

    ??
    /**?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

    java代碼:?


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

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





    (2)order by field1 desc, field2

    java代碼:?


    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.過濾條件的排列組合
    (多謝shinwell指正,我改正了后面的代碼)

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

    java代碼:?


    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?addFilters(FileFilter[]?filterArray){?
    ????
    if(filterArray?==?null){?
    ??????
    return;?
    ????}
    ?

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

    ??
    /**?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類的代碼
    java代碼:?


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

    public?class?ReverseFilter?implements?FileFilter?{?
    ??
    /**?the?original?filter*/?
    ??
    private?FileFilter?originalFilter?=?null;?

    ??
    /**?constructor?takes?a?filter?as?parameter?*/?
    ??
    public?ReverseFilter(FileFilter?filter){?
    ????originalFilter?
    =?filter;?
    ??}
    ?

    ??
    /**?must?meet?all?the?filter?condition?*/?
    ??
    public?boolean?accept(File?pathname)?{?
    ??????
    return?!originalFilter.accept(pathname);?
    ??}
    ?
    }
    ?




    5.總結
    本文講述了Design Pattern的分析和實踐,并闡述了一類條件組合問題的解決思路。
    posted on 2006-04-24 09:23 Long Long Ago 閱讀(430) 評論(0)  編輯  收藏 所屬分類: others
    主站蜘蛛池模板: 男女猛烈xx00免费视频试看| 国产午夜精品久久久久免费视| 又粗又黄又猛又爽大片免费| 男女猛烈无遮掩视频免费软件| 亚洲欧洲美洲无码精品VA | 最好免费观看高清在线| 亚洲电影一区二区三区| 在线jlzzjlzz免费播放| 精品人妻系列无码人妻免费视频| 亚洲狠狠狠一区二区三区| 免费A级毛片无码A| 3344免费播放观看视频| 草久免费在线观看网站| 亚洲黄网在线观看| 91麻豆国产自产在线观看亚洲 | 午夜两性色视频免费网站| 你好老叔电影观看免费| 亚洲日韩亚洲另类激情文学| 亚洲色大成网站WWW久久九九| 黄在线观看www免费看| eeuss免费天堂影院| 野花香高清视频在线观看免费 | 免费一级e一片在线播放| 18成禁人视频免费网站| 午夜在线免费视频 | 一级**爱片免费视频| 亚洲日本人成中文字幕| 国产亚洲成av片在线观看| 国产免费人视频在线观看免费| 在线日本高清免费不卡| 中文字幕不卡高清免费| 爱情岛论坛亚洲品质自拍视频网站| 亚洲的天堂av无码| 亚洲人成精品久久久久| 国产精品另类激情久久久免费| 色老头永久免费网站| 日本一区午夜艳熟免费| 国产亚洲精品2021自在线| 在线亚洲高清揄拍自拍一品区| 亚洲国产精品久久久久久| 亚洲综合色自拍一区|