PC的blog

          Finding... Thinking... Solving...

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            9 Posts :: 0 Stories :: 54 Comments :: 0 Trackbacks
          本文緊接使用重構移除丑陋的if else代碼(2)

          移除if else

          首先仔細觀察一 下updateState()方法,我們會發現,導致該方法內存在大量if else的原因是它的參數僅僅是一個enum。由于enum本身并不含有任何邏輯代碼,因此導致處理enum的方法需要使用if else來分析enum然后調用相應的邏輯。明白了這個道理之后,重構的方向就明了了。簡單的說,我們需要要將方法參數由enum替換成一個更加強壯的抽 象類,每一個繼承該類的子類將具體負責處理一個enum實例,之后再將updateState()方法中相應的邏輯代碼轉移到這些子類中。這樣處理之后, 令人討厭的if else就會消失了。


          我們將這個替換enum的抽象類命名為SystemStatePerformer,代碼如下:

          package de.jingge.refactoring;

           

          import java.awt.Image;


          public abstract class SystemStatePerformer {

              
          private final SystemState state;

              
          private Image image;

              
          public SystemStatePerformer(SystemState state, Image image) {

                  
          this.state = state;

                  
          this.image = image;

              }

              
          public SystemState getState() {

                  
          return state;

              }

              
          public Image getImage() {

                  
          return image;

              }
              
              
          public abstract void perform();

          }

          從代碼中可以看出,每 一個performer都含義有一個SystemState,這個SystemState屬性,將只能通過構建器映射方式射入一個performer的對 象實例。換句話說SystemState只是一個只讀屬性,而且每一個performer實體類都只負責處理一個enum的實例(下面馬上會解釋如何實現 的)。這里使用的Image作為一個例子,它表示用戶的每一個狀態都可以使用一個圖標來表示。performer()方法將負責處理具體的邏輯。這個 SystemStatePerformer的實體子類可以引用任何類型的對象,然后在perform()方法里面進行調用。




          下 一步就是編寫SystemStatePerformer的實體子類。我首先想到的是為每一個enum實例編寫一個實際的子類,理論上來說是沒問題的,但是 這樣做必須編寫一大堆的子類,不便于管理。所以我決定使用Factory + annonymous classes來構建具體的實體子類,讓Factory來管理所有的實體子類。 代碼如下:

          package de.jingge.refactoring;

           

          import static de.jingge.refactoring.SystemState.*;

          import java.awt.Image;

          import java.awt.image.BufferedImage;


          public class SystemStatePerformerFactory {

           

          private static SystemStatePerformerFactory INSTANCE = new SystemStatePerformerFactory();

             

              
          private SystemStatePerformerFactory() {

          }

           

              
          public static SystemStatePerformer getSystemStatePerformer(SystemState state) {

                  
          switch (state) {

                      
          case LOGGEDIN:

                          
          return createLoggedInPerformer();

                      
          case IDLE:

                          
          return createIdlePerformer();

                      
          case LOGGEDOUT:

                          
          return createLoggedOutPerformer();

                      
          default:

                          
          throw new IllegalAccessError("Unkonw status");

                  }

              }

           

              
          private static SystemStatePerformer createLoggedInPerformer() {

                  
          return new SystemStatePerformer(LOGGEDIN, getImage("loggedin.gif")) {

           

                      @Override

                      
          public void perform() {

                          
          // do something after logging in is successful,

                          
          // for example: show welcome dialog, open the last edit document, etc.

                      }

                  };

              }

           

              
          private static SystemStatePerformer createLoggedOutPerformer() {

                  
          return new SystemStatePerformer(LOGGEDOUT, getImage("loggedout.gif")) {

           

                      @Override

                      
          public void perform() {

                          
          // do something after logging out is successful,

                          
          // for example: free used resource, dispose GUI components, etc.            }

                      }

                  };

              }

           

              
          private static SystemStatePerformer createIdlePerformer() {

                  
          return new SystemStatePerformer(IDLE, getImage("idle.gif")) {

           

                      @Override

                      
          public void perform() {

                          
          // do something after the user is idle,

                          
          // for example: save the application state temporarily, lock the application, etc.

                      }

                  };

              }

           

              
          private static Image getImage(String string) {

                  
          return new BufferedImage(1010, BufferedImage.TYPE_4BYTE_ABGR);

              }

          }

          從 代碼中可以看到,針對每一個enum狀態都有一個創建performer的方法,該方法返回一個匿名類。邏輯代碼將會被轉移至個匿名類的 perform()方法之內。整個Factory只有一個公開的方 法:getSystemStatePerformer(SystemState),SystemManager可以調用這個方法來獲得相應的 Performer實例。


          在 這篇文章中,我希望專屬于if else的問題。對于其他設計方面的問題,我采取的態度是能省略就省略。實際開發中,還有有很多問題需要處理,例如,使用static方法會導致系統的可 測試性下降,在實際開發中應該盡量避免,解決這類問題的方法之一是使用DI框架,例如Google Guice。

          下一篇文章使用重構移除丑陋的if else代碼(4)繼續講解。




          聲明:本文版權歸作者所有,如需轉載請注明出處。

          posted on 2008-08-04 02:54 polygoncell 閱讀(2249) 評論(4)  編輯  收藏

          Feedback

          # re: 使用重構移除丑陋的if else代碼(3) 2008-08-04 06:58 游客
          你的做法在某些情況下是非常適合的
          但 if else 在某些復雜的業務邏輯中是無法避免的  回復  更多評論
            

          # re: 使用重構移除丑陋的if else代碼(3) 2008-08-04 11:50 殘夢追月
          呵呵,看到這里,我明白你是怎么做的老!  回復  更多評論
            

          # re: 使用重構移除丑陋的if else代碼(3) 2008-09-25 10:47 iridiumcao
          這里用了switch...case的方式,不是if...else變體嗎?

          那么這個重構雖然形式上去掉了if...else,但代碼復雜度反而增加了。

          個人覺得前文把int換成enum型就足夠了,不必再往后重構。  回復  更多評論
            

          # re: 使用重構移除丑陋的if else代碼(3) 2013-03-20 15:38 000
          00000  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 百色市| 巨野县| 芦山县| 定州市| 凌海市| 和政县| 溧阳市| 米易县| 门头沟区| 仙居县| 巴南区| 阿勒泰市| 海安县| 钟祥市| 新建县| 东安县| 获嘉县| 阿坝县| 永靖县| 墨竹工卡县| 顺昌县| 汶上县| 临邑县| 石城县| 安溪县| 汾西县| 三穗县| 凤阳县| 平谷区| 平武县| 罗田县| 疏勒县| 海盐县| 香格里拉县| 泰州市| 南华县| 麟游县| 宁武县| 海门市| 富阳市| 南通市|