PC的blog

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

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

          移除if else

          首先仔細(xì)觀察一 下updateState()方法,我們會(huì)發(fā)現(xiàn),導(dǎo)致該方法內(nèi)存在大量if else的原因是它的參數(shù)僅僅是一個(gè)enum。由于enum本身并不含有任何邏輯代碼,因此導(dǎo)致處理enum的方法需要使用if else來(lái)分析enum然后調(diào)用相應(yīng)的邏輯。明白了這個(gè)道理之后,重構(gòu)的方向就明了了。簡(jiǎn)單的說(shuō),我們需要要將方法參數(shù)由enum替換成一個(gè)更加強(qiáng)壯的抽 象類,每一個(gè)繼承該類的子類將具體負(fù)責(zé)處理一個(gè)enum實(shí)例,之后再將updateState()方法中相應(yīng)的邏輯代碼轉(zhuǎn)移到這些子類中。這樣處理之后, 令人討厭的if else就會(huì)消失了。


          我們將這個(gè)替換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();

          }

          從代碼中可以看出,每 一個(gè)performer都含義有一個(gè)SystemState,這個(gè)SystemState屬性,將只能通過(guò)構(gòu)建器映射方式射入一個(gè)performer的對(duì) 象實(shí)例。換句話說(shuō)SystemState只是一個(gè)只讀屬性,而且每一個(gè)performer實(shí)體類都只負(fù)責(zé)處理一個(gè)enum的實(shí)例(下面馬上會(huì)解釋如何實(shí)現(xiàn) 的)。這里使用的Image作為一個(gè)例子,它表示用戶的每一個(gè)狀態(tài)都可以使用一個(gè)圖標(biāo)來(lái)表示。performer()方法將負(fù)責(zé)處理具體的邏輯。這個(gè) SystemStatePerformer的實(shí)體子類可以引用任何類型的對(duì)象,然后在perform()方法里面進(jìn)行調(diào)用。




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

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

              }

          }

          從 代碼中可以看到,針對(duì)每一個(gè)enum狀態(tài)都有一個(gè)創(chuàng)建performer的方法,該方法返回一個(gè)匿名類。邏輯代碼將會(huì)被轉(zhuǎn)移至個(gè)匿名類的 perform()方法之內(nèi)。整個(gè)Factory只有一個(gè)公開的方 法:getSystemStatePerformer(SystemState),SystemManager可以調(diào)用這個(gè)方法來(lái)獲得相應(yīng)的 Performer實(shí)例。


          在 這篇文章中,我希望專屬于if else的問(wèn)題。對(duì)于其他設(shè)計(jì)方面的問(wèn)題,我采取的態(tài)度是能省略就省略。實(shí)際開發(fā)中,還有有很多問(wèn)題需要處理,例如,使用static方法會(huì)導(dǎo)致系統(tǒng)的可 測(cè)試性下降,在實(shí)際開發(fā)中應(yīng)該盡量避免,解決這類問(wèn)題的方法之一是使用DI框架,例如Google Guice。

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




          聲明:本文版權(quán)歸作者所有,如需轉(zhuǎn)載請(qǐng)注明出處。

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

          Feedback

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

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

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

          那么這個(gè)重構(gòu)雖然形式上去掉了if...else,但代碼復(fù)雜度反而增加了。

          個(gè)人覺得前文把int換成enum型就足夠了,不必再往后重構(gòu)。  回復(fù)  更多評(píng)論
            

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


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 辽宁省| 镇雄县| 宁夏| 伊川县| 惠来县| 海口市| 宁化县| 白朗县| 桂东县| 江永县| 望都县| 会昌县| 静乐县| 车险| 卢龙县| 乐山市| 株洲县| 漯河市| 河东区| 瑞丽市| 合水县| 大竹县| 革吉县| 灵丘县| 商南县| 昌吉市| 长岭县| 隆尧县| 沽源县| 罗源县| 蓬溪县| 青龙| 互助| 铜山县| 梅州市| 建宁县| 宁阳县| 新民市| 卢龙县| 旺苍县| 永定县|