1. 程式人生 > >用設計模式來代替臃腫的ifelse層層判斷

用設計模式來代替臃腫的ifelse層層判斷

--------------------------------<程式碼優化之避免使用過多ifelse>---------------------------------


在www.infoq.com/cn網站上看了一本書叫《ThoughtWorks文集》,裡邊有一章講的是“物件健身操”,其中提到了“拒絕使用else關鍵字”。那麼如何“拒絕使用else關鍵字”呢?
      
       1、如果程式中只有一個else,如下:
            if(con){
                  dosomething();
            }else{
                  dootherthings();
            }
        可以如下拒絕else:
            if(con){
                  dosomething();
                  return;
            }
            dootherthings();
         或者使用三元運算子:con ? dosometing() : dootherthings();
 
        2、如果程式中有多個else,如下:
            if(con1){
                  dothing1();
            }else if(con2){
                  dothing2();
            }else if(con3){
                  dothing3();
            }......
        可是使用策略模式或多型機制來拒絕else(還有很多其他方式),下面先介紹“策略模式”的方式:
        首先講一個使用if...else...的例子:
        package ifelse.use;
        public class UseIfElse {
            public static void main(String args[]){
                MyPaper myPaper = new MyPaper(PaperColor.RED);
                if(myPaper.getMyPaperColor() == PaperColor.BLACK){
                    System.out.println("You need a black pen!");
                }else if(myPaper.getMyPaperColor() == PaperColor.BLUE){
                    System.out.println("You need a blue pen!");
                }else if(myPaper.getMyPaperColor() == PaperColor.RED){
                    System.out.println("You need a red pen!");
                }else if(myPaper.getMyPaperColor() == PaperColor.WHITE){
                    System.out.println("You need a white pen!");
                }
           }
       }
       class MyPaper{
           private PaperColor paperColor;
           public MyPaper(PaperColor paperColor){
               this.paperColor = paperColor;
           }
           public PaperColor getMyPaperColor(){
               return this.paperColor;
           }
       }
       enum PaperColor{
           WHITE, BLACK, BLUE, RED
       }
 
       使用if...else...的弊端在於:不利於對程式的擴充套件,如果新添加了一個顏色型別,那麼就得去修改程式再新增一個if...else...分支,根據“開-閉原則”的宗旨:對擴充套件開,對修改閉。顯然是用if...else...已經go out了。
       下面講一個使用“策略模式”解決上述問題的辦法:
       package ifelse.no;
       public class NoIfElse {
           public static void main(String args[]){
               MyPaper myPaper = new MyPaper(new White());
               myPaper.choicePen();
          }
       }
       interface PaperColor{
           public void getPenColor();
       }
       class White implements PaperColor{
           public void getPenColor(){
               System.out.println("You need a white pen!");
           }
       }
       class Red implements PaperColor{
           public void getPenColor(){
               System.out.println("You need a red pen!");
           }
       }
       class Blue implements PaperColor{
           public void getPenColor(){
               System.out.println("You need a blue pen!");
           }
       }
       class Black implements PaperColor{
           public void getPenColor(){
               System.out.println("You need a black pen!");
           }
       }
       class MyPaper{
           private PaperColor paperColor;
           public MyPaper(PaperColor paperColor){
               this.paperColor = paperColor;
           }
           public PaperColor getPaperColor(){
               return this.paperColor;
           }
           public void choicePen(){
               this.paperColor.getPenColor();
           }
      }
 
總結:
     if...else...的每個分支語句都做一件事,因此我們可以把這麼些事單獨封裝在一個類中,就有了White、Blue、Red、Black4個類,這四個類都實現了介面PaperColor,我們再定義一個MyPaper的類(此類具有類似負載均衡的作用,分按照不同的請求分別呼叫跟前面4個類中的一個)。這樣就把if...else...遮蔽掉了。
 
    接下來介紹使用“多型”機制來實現拒絕else:
    package ifelse.no.Polymorphism;
    public class NoIfElse_Polymorphism {
        public static void main(String args[]){
            MyPaper myPaper = new MyPaper();
            myPaper.choice(new Black());
        }
    }
    class White {
        public void getPenColor(){
            System.out.println("You need a white pen!");
        }
    }
    class Red {
        public void getPenColor(){
            System.out.println("You need a red pen!");
        }
    }
    class Blue {
        public void getPenColor(){
            System.out.println("You need a blue pen!");
        }
    }
    class Black {
        public void getPenColor(){
            System.out.println("You need a black pen!");
        }
    }
    class MyPaper{
        public void choice(White white){
            white.getPenColor();
        }
        public void choice(Red red){
            red.getPenColor();
        }
        public void choice(Blue blue){
            blue.getPenColor();
        }
        public void choice(Black black){
            black.getPenColor();
        }
    }
總結:
      此處使用的多型機制指:方法的重構,根據方法名相同兒引數不同的機制,來實現拒絕關鍵字。
 
注意:上述兩種方式適用於同時只有一個分支被執行的情況。
參考:“java設計模式”之“策略模式”。


=================================<程式碼優化之避免使用過多ifelse>======================================