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

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

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

    love fish大鵬一曰同風(fēng)起,扶搖直上九萬里

    常用鏈接

    統(tǒng)計(jì)

    積分與排名

    friends

    link

    最新評論

    能為你的程序錦上添花的幾種程序結(jié)構(gòu)(轉(zhuǎn))

    一."用到再說"結(jié)構(gòu).
    如果有一個(gè)類有一個(gè)集合成員,可以在為此成員添加元素時(shí)再把具體集合建立起來,以免浪費(fèi)空間和時(shí)間.

    例:

     1 public class Company{
     2     private List members=null;
     3 
     4     public void addMember(Member member){
     5      if(members=null){
     6     members=new ArrayList();
     7       }
     8 
     9      members.add(member);
    10     }
    11 }
    12 


    異曲同工的另外一個(gè)例子:

     1 public class Singleton{
     2        private static Singleton instance=null;
     3 
     4        public static synchronized Singleton getInstance(){
     5    // 要用的時(shí)候再把Singleton建立起來
     6    if(instance==null){
     7      instance=new Singleton();
     8    }       
     9 
    10    return instance;
    11        }
    12 }
    13 

     

    二."試試再說"結(jié)構(gòu)
    從集合中取區(qū)間元素時(shí),可以直接從上下限之間取來,讓try...catch...去處理越界的事.

    題設(shè):有個(gè)數(shù)不定元素的列表(allTodoes),需要從中取N個(gè),起始位置不限,你怎么編寫程序.

    很多人開始進(jìn)行越界的判斷,出來一堆if else,有時(shí)還需要在紙上寫好思路,完畢后還有多方測試,生怕出錯(cuò),即使編寫好后其他人維護(hù)起來也是小心翼翼的.其實(shí)沒必要這么麻煩.

    例.

     1   int start=pageIndex*pageSize;
     2   int end=start+pageSize;
     3   
     4   for(int i=start;i<end;i++){
     5    try{
     6     todoResult.addTodo((Todo)allTodoes.get(i));
     7    }
     8    catch(Exception ex){
     9     continue;
    10    }
    11   }

    題外話:分支和循環(huán)語句天生就不容易理解,尤其是在嵌套較深的時(shí)候,因?yàn)檫@是機(jī)器的思維特性.還是try...catch...比較貼近人類思維.


    三."憑文件領(lǐng)人"結(jié)構(gòu)
    在查詢中,如果把查詢條件和遴選過程分開來更有益,程序也因此解耦合.這才是OO化的查詢.

    需求:從公司的職員列表中,找出男性且年齡大于22的成員.

    傳統(tǒng)寫法: 

     1  List allmembers=company.getMembers();// 取得所有成員
     2   List results=new ArrayList();// 結(jié)果列表
     3   
     4   for(Iterator it=allmembers.iterator();it.hasNext();){
     5    Member member=(Member)it.next();
     6    
     7    if(member.getAge()>22 && member.isMale()){  // 篩選,這里是把查詢條件和遴選過程融合在一起,條件一變立即就得加個(gè)分支.
     8     results.add(member);
     9    }
    10   } 
    11 

     

    這種寫法沒有錯(cuò),但是不是面向?qū)ο蟮膶懛?它有以下缺陷:
    1.查詢條件和篩選過程沒有分離.
    2.這樣寫的后果使Company變成了一個(gè)失血模型而不是領(lǐng)域模型.
    3.換查詢條件的話,上面除了"篩選"一句有變化外其它都是模板代碼,重復(fù)性很高.

    真正符合OO的查詢應(yīng)該是這樣:

    1   MemberFilter filter1=new MemberFilter(){
    2    public boolean accept(Member member) {
    3         return member.isMale() && member.getAge()>22;
    4    }
    5   };
    6   
    7   List ls=company.listMembers(filter1);

     

    這段代碼成功的把查詢條件作為一個(gè)接口分離了出去,接口代碼如下:

    1 public interface MemberFilter{
    2  public boolean accept(Member member); 
    3 }

    而類Company增加了這樣一個(gè)函數(shù):

     1  public List listMembers(MemberFilter memberFilter){
     2   List retval=new ArrayList();
     3   
     4   for(Iterator it=members.iterator();it.hasNext();){
     5    Member member=(Member)it.next();
     6    
     7    if(memberFilter.accept(member)){
     8     retval.add(member);
     9    }
    10   }  
    11   
    12   return retval;
    13  }

    這就把模板代碼歸結(jié)到了類內(nèi)部,外面不會(huì)重復(fù)書寫了.Company也同時(shí)擁有了數(shù)據(jù)和行為,而不是原來的數(shù)據(jù)容器了.

    四."查表"結(jié)構(gòu)
    這種結(jié)構(gòu)將多個(gè)分支語句變換為一個(gè)查表結(jié)構(gòu),這樣做對擴(kuò)充程序結(jié)構(gòu),修改具體數(shù)額都很方便,使程序更易于維護(hù).還可以把歸結(jié)出的表結(jié)構(gòu)放在持久介質(zhì)中如XML文件,數(shù)據(jù)庫等,用到的時(shí)候再取,這樣做在條件變化時(shí)不需要修改程序.

    原始代碼(VB代碼,但應(yīng)該不妨礙理解):

     1 Dim count1 
     2 count1 = salary.Value + USA.Value * Drate + JAN.Value * Jrate - 4000 
     3 If count1 < 500 Then 
     4  tax.Value = count1 * 0.05 
     5 ElseIf count1 < 2000 Then 
     6  tax.Value = count1 * 0.1 - 25 
     7 ElseIf count1 < 5000 Then 
     8  tax.Value = count1 * 0.15 - 125 
     9 ElseIf count1 < 20000 Then 
    10  tax.Value = count1 * 0.2 - 375 
    11 ElseIf count1 < 40000 Then 
    12  tax.Value = count1 * 0.25 - 1375 
    13 ElseIf count1 < 60000 Then 
    14  tax.Value = count1 * 0.3 - 3375 
    15 Else 
    16  tax.Value = count1 * 0.3 - 3375 
    17 End If 

     

    變換如下:
    這是個(gè)稅率計(jì)算的語句段,公式是確定的:稅=月薪*稅率-折扣,稅率又和月薪有關(guān)系,月薪越高稅率越高,首先這里可以歸納出一個(gè)基本類:

     1 public class TaxItem{
     2  float limit; // 月薪界限
     3  float ratio;// 稅率
     4  float discount;// 折扣
     5 
     6  public TaxItem(float limit,float ratio,float discount){
     7   this.limit=limit;
     8   this.ratio=ratio;
     9   this.discount=discount;
    10  }
    11 
    12  public TaxItem(){
    13   this(0.0f,0.0f,0.0f);
    14  }
    15 
    16  public float getDiscount() {
    17   return discount;
    18  }
    19 
    20  public float getLimit() {
    21   return limit;
    22  }
    23 
    24  public float getRatio() {
    25   return ratio;
    26  }
    27 }
    28 
    29 


    然后就是稅計(jì)算類:

     1 public class TaxCaculator{
     2         private static ArrayList list=new ArrayList();
     3         
     4         public TaxCaculator(){
     5                 // 這里把各個(gè)等級加入到鏈表中,注意添加順序是由小到大
     6                 list.add(new TaxItem(500.0f,0.05f,0.0f));
     7                 list.add(new TaxItem(2000.0f,0.1f,25.0f));
     8                 list.add(new TaxItem(5000.0f,0.15f,125.0f));
     9                 list.add(new TaxItem(20000.0f,0.2f,375.0f));
    10                 list.add(new TaxItem(40000.0f,0.25f,1375.0f));
    11                 list.add(new TaxItem(60000.0f,0.3f,3375.0f));
    12         }
    13         
    14         // 這個(gè)函數(shù)用來計(jì)算所得稅
    15         public float getTax(float salary){
    16                 TaxItem item=new TaxItem();
    17                 
    18                 for(int i=0;i<list.size();i++){
    19                         item=(TaxItem)list.get(i);
    20                         
    21                         if(salary>item.getLimit()){
    22                                 continue;
    23                         }
    24                         else{
    25                                 break;
    26                         }
    27                 }               
    28                 
    29                 // 返回最終結(jié)果,當(dāng)然,這個(gè)公式也可以放在TaxItem 類中,這里就見仁見智了。
    30                 return salary*item.getRatio()-item.getDiscount();
    31         }
    32 }



    調(diào)用如下 :

     1                 TaxCaculator taxCaculator=new TaxCaculator();
     2                 
     3                 float salary=1000.f;    
     4                 System.out.println("Salary="+salary +" Tax="+taxCaculator.getTax(salary));
     5                 
     6                 salary=2000.f;  
     7                 System.out.println("Salary="+salary +" Tax="+taxCaculator.getTax(salary));
     8                 
     9                 salary=3000.f;  
    10                 System.out.println("Salary="+salary +" Tax="+taxCaculator.getTax(salary));


     

    五."分而治之"結(jié)構(gòu)
    該結(jié)構(gòu)將分支語句的執(zhí)行部分分散到單獨(dú)的類中處理,降低了系統(tǒng)耦合度,程序也更容易維護(hù).

    舉例如下:
    在日常工作中,我們經(jīng)常需要解析一段字符串并交由相應(yīng)的函數(shù)進(jìn)行處理,例如TCP/IP通信中的命令解析和用戶自定義文件解析等場合,通常的處理方法是這樣:

    if(命令==”AAA”){
        函數(shù)AAA執(zhí)行;
    }
    else if(命令==”BBB”){
        函數(shù)BBB執(zhí)行;
    }
    .
    .
    .
    else{
        函數(shù)XXX執(zhí)行;
    }

    這種方法在命令較少時(shí)是有效的,當(dāng)命令眾多時(shí),if語句和相關(guān)的函數(shù)將會(huì)形成一個(gè)巨集,給檢查,維護(hù)和擴(kuò)充帶來了很大的不便,久而久之將會(huì)成為系統(tǒng)性能提升的瓶頸。

    一個(gè)成功的軟件程序必須盡可能簡單并易于重構(gòu)和擴(kuò)展,在命令模式和Java反射機(jī)制的幫助下,我們可以從容解決上述問題,達(dá)到簡單并易于重構(gòu)和擴(kuò)展的要求。以下將簡要說明解決方案。

    1. 制作一個(gè)命令的抽象接口.

    1 public interface Command{ 
    2        public abstract void execute(String[] args); 
    3 

     

    2. 讓每種命令都實(shí)現(xiàn)這個(gè)接口.

     1 // 命令一 
     2 public class CommandType01 implements Command{ 
     3        public void execute(String[] args){ 
     4                System.out.println("\n commandType01 start!");           
     5                System.out.print("\t commandType01 Length="+args.length);                
     6                System.out.println("\n commandType01 End!"); 
     7        } 
     8 
     9 
    10 // 命令二 
    11 public class CommandType02 implements Command{ 
    12        public void execute(String[] args){ 
    13                System.out.println("\n commandType02 start!");           
    14                 
    15                System.out.print("\t commandType02 is:");                
    16                for(String item:args){ 
    17                        System.out.print("\t "+item); 
    18                } 
    19                 
    20                System.out.println("\n commandType02 End!"); 
    21        } 
    22 
    23 
    24 // 命令三 
    25 public class CommandType03 implements Command{ 
    26        public void execute(String[] args){ 
    27                System.out.println("\n commandType03 start!");           
    28                System.out.print("\t commandType03 last Nation="+args[args.length-1]);           
    29                System.out.println("\n commandType03 End!"); 
    30        } 
    31 
    32 
    33 


    讓每種命令都實(shí)現(xiàn)execute接口的用意是強(qiáng)制每個(gè)命令的執(zhí)行方式一致,簡化調(diào)用時(shí)的處理,但執(zhí)行內(nèi)容應(yīng)該根據(jù)實(shí)際情況決定.
    例如
    命令一的執(zhí)行內(nèi)容是輸出參數(shù)的個(gè)數(shù)
    命令二的執(zhí)行內(nèi)容是輸出參數(shù)的內(nèi)容
    命令二的執(zhí)行內(nèi)容是輸出最后一個(gè)參數(shù)

    3. 將命令防置到命令中心中去
    命令中心類的代碼如下:

     1 public class Mediation{ 
     2        Command cmmd;// 命令對象的引用 
     3        String[] cmmdArgs;// 參數(shù)列表 
     4         
     5        public Mediation(){ 
     6                 
     7        } 
     8         
     9        public void fetchCommand(String strCmmd){ 
    10                cmmdArgs=strCmmd.split("\s+");// 分析原始命令 
    11                 
    12                String className="Command"+cmmdArgs[0];// 根據(jù)分析后命令的第一個(gè)參數(shù)得到類名 
    13                 
    14                try
    15                        Class cls=Class.forName(className);// 利用反射機(jī)制得到類 
    16                        cmmd=(Command)cls.newInstance();// 由類得到類實(shí)例 
    17                } 
    18                catch(Exception ex){ 
    19                        ex.printStackTrace(); 
    20                }                
    21        }        
    22 
    23         
    24        public void executeCommand(){ 
    25                cmmd.execute(cmmdArgs);// 執(zhí)行命令對象的execute方法 
    26        } 
    27 
    28 


    4.執(zhí)行過程

     1                Mediation mediation = new Mediation(); 
     2                // 取得命令一并執(zhí)行 
     3                mediation.fetchCommand("Type01  AB CD"); 
     4                mediation.executeCommand(); 
     5 
     6                // 取得命令二并執(zhí)行 
     7                mediation.fetchCommand("Type02  1 2 3 4"); 
     8                mediation.executeCommand(); 
     9 
    10                // 取得命令三并執(zhí)行 
    11                mediation.fetchCommand("Type03  USA  Russia China"); 
    12                mediation.executeCommand(); 
    13 

    執(zhí)行效果如下:
    commandType01 start!
            commandType01 Length=3
    commandType01 End!

    commandType02 start!
            commandType02 is:       Type02  1       2       3       4
    commandType02 End!

    commandType03 start!
            commandType03 last Nation=China
    commandType03 End!

    由上可見,我們使用反射機(jī)制消除了龐大的分支語句,把命令的執(zhí)行過程分散到了Command的各個(gè)子類中,降低了命令類和控制中心類的耦合程度,達(dá)到了簡單并易于重構(gòu)和擴(kuò)展的要求。如果新增一種命令,只需增加Command的一個(gè)子類就可以了。
    很多情況下命令的execute函數(shù)需要命令中心類或者其它類的信息,這時(shí)可以在Command接口類和Command的子類中間添加一個(gè)類CommandBase,在其中包含一個(gè)命令中心類或者其它類的引用,并增加相應(yīng)的getter/setter函數(shù),Command的子類繼承這個(gè)類并實(shí)現(xiàn)Command的接口即可,最后在fetchCommand函數(shù)中傳入中心類或者其它類的引用即可。

    注意:這里對命令和Command的子類類名有特殊要求,即一種命令對應(yīng)一種子類,子類類名可以由命令的首個(gè)參數(shù)簡單組合而來,否則還是避免不了分支語句。

     

    以上五種結(jié)構(gòu)如果多加注意,應(yīng)該能起到錦上添花的效果.

    posted on 2007-06-05 13:26 liaojiyong 閱讀(1010) 評論(1)  編輯  收藏 所屬分類: Java

    評論

    # re: 能為你的程序錦上添花的幾種程序結(jié)構(gòu)(轉(zhuǎn))[未登錄] 2008-08-13 23:39 sa

    sa  回復(fù)  更多評論   

    主站蜘蛛池模板: 午夜宅男在线永久免费观看网| 91青青国产在线观看免费| jizz免费观看| 久久久免费的精品| 美女视频黄是免费的网址| 日产乱码一卡二卡三免费| 综合亚洲伊人午夜网| 亚洲专区先锋影音| 亚洲变态另类一区二区三区| 窝窝影视午夜看片免费| 最近国语视频在线观看免费播放| 久久永久免费人妻精品下载 | 三上悠亚在线观看免费| 99re6热视频精品免费观看 | 免费观看AV片在线播放| 午夜两性色视频免费网站| 国产成人精品曰本亚洲79ren| 亚洲视频一区二区三区| 豆国产96在线|亚洲| 国产精品99久久免费观看| 在线中文高清资源免费观看| 亚洲人成影院在线无码按摩店| 亚洲六月丁香六月婷婷蜜芽| 免费很黄无遮挡的视频毛片| 亚洲精品国产免费| 亚洲国产人成精品| 亚洲国产中文在线视频 | 亚洲高清国产拍精品熟女| a毛片免费在线观看| 99精品全国免费观看视频| 亚洲欧洲日产国码无码网站| 亚洲综合久久精品无码色欲| 99久久成人国产精品免费| 天天干在线免费视频| 亚洲成在人天堂在线| 曰批免费视频播放在线看片二 | 在线观看免费中文视频| 亚洲Av无码国产情品久久| 亚洲毛片在线免费观看| 一级人做人a爰免费视频| 67194成是人免费无码|