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

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

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

    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 閱讀(2244) 評論(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  回復  更多評論
      


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


    網站導航:
     
    主站蜘蛛池模板: 猫咪免费人成网站在线观看| 特级做a爰片毛片免费看| 免费在线中文日本| 最新亚洲成av人免费看| a级毛片免费观看在线| 亚洲欧洲日产国码高潮αv| 成人免费夜片在线观看| 亚洲国产综合无码一区二区二三区| 国产精品亚洲专一区二区三区| 麻豆国产入口在线观看免费| 精品久久久久久久久亚洲偷窥女厕| 免费高清av一区二区三区| 大桥未久亚洲无av码在线| 又粗又硬又大又爽免费视频播放| 白白色免费在线视频| 亚洲宅男天堂在线观看无病毒| 国产精品hd免费观看| 亚洲国产精品成人精品无码区 | 精品亚洲麻豆1区2区3区| 95免费观看体验区视频| 亚洲精品福利你懂| 日韩视频在线免费观看| 一级毛片免费视频网站| 国产成人A人亚洲精品无码| 91热成人精品国产免费| 亚洲欧美日韩中文高清www777| 国产在线ts人妖免费视频| 本免费AV无码专区一区| 亚洲第一精品电影网| 拔擦拔擦8x华人免费久久| 无码 免费 国产在线观看91| 亚洲高清国产拍精品26U| 最近的免费中文字幕视频| 四虎国产精品永免费| 亚洲色图校园春色| 四虎永久成人免费| 免费毛片a线观看| 亚洲国产成人AV在线播放| 精品久久久久久亚洲| 麻豆国产精品免费视频| xxxxxx日本处大片免费看|