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

    移除if else

    首先仔細觀察一 下updateState()方法,我們會發(fā)現(xiàn),導(dǎo)致該方法內(nèi)存在大量if else的原因是它的參數(shù)僅僅是一個enum。由于enum本身并不含有任何邏輯代碼,因此導(dǎo)致處理enum的方法需要使用if else來分析enum然后調(diào)用相應(yīng)的邏輯。明白了這個道理之后,重構(gòu)的方向就明了了。簡單的說,我們需要要將方法參數(shù)由enum替換成一個更加強壯的抽 象類,每一個繼承該類的子類將具體負責(zé)處理一個enum實例,之后再將updateState()方法中相應(yīng)的邏輯代碼轉(zhuǎn)移到這些子類中。這樣處理之后, 令人討厭的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屬性,將只能通過構(gòu)建器映射方式射入一個performer的對 象實例。換句話說SystemState只是一個只讀屬性,而且每一個performer實體類都只負責(zé)處理一個enum的實例(下面馬上會解釋如何實現(xiàn) 的)。這里使用的Image作為一個例子,它表示用戶的每一個狀態(tài)都可以使用一個圖標(biāo)來表示。performer()方法將負責(zé)處理具體的邏輯。這個 SystemStatePerformer的實體子類可以引用任何類型的對象,然后在perform()方法里面進行調(diào)用。




    下 一步就是編寫SystemStatePerformer的實體子類。我首先想到的是為每一個enum實例編寫一個實際的子類,理論上來說是沒問題的,但是 這樣做必須編寫一大堆的子類,不便于管理。所以我決定使用Factory + annonymous classes來構(gòu)建具體的實體子類,讓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狀態(tài)都有一個創(chuàng)建performer的方法,該方法返回一個匿名類。邏輯代碼將會被轉(zhuǎn)移至個匿名類的 perform()方法之內(nèi)。整個Factory只有一個公開的方 法:getSystemStatePerformer(SystemState),SystemManager可以調(diào)用這個方法來獲得相應(yīng)的 Performer實例。


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

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




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

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

    Feedback

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

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

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

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

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

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


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲码和欧洲码一码二码三码| 亚洲AV日韩精品久久久久| 亚洲色偷偷综合亚洲AV伊人蜜桃| 99热精品在线免费观看| 亚洲一区免费观看| 亚洲精品免费在线视频| 亚洲视频免费播放| 国产啪精品视频网免费| 亚洲色精品VR一区区三区| 欧美a级成人网站免费| 久久综合久久综合亚洲| 日韩视频在线免费| 免费人成视频在线观看免费| 亚洲精品线路一在线观看| h片在线观看免费| 亚洲av无码专区国产乱码在线观看 | 4455永久在线观免费看| 亚洲AV一二三区成人影片| 女性自慰aⅴ片高清免费| 美女裸体无遮挡免费视频网站| 亚洲精品色婷婷在线影院| baoyu122.永久免费视频| 亚洲成AV人片在线观看无| 午夜影院免费观看| 成人区精品一区二区不卡亚洲| 日韩毛片免费在线观看| 夜夜爽妓女8888视频免费观看| 亚洲精品二区国产综合野狼| 精品无码免费专区毛片| 亚洲AV成人无码网站| 国产成人亚洲综合无码| 亚洲毛片免费观看| 美女视频黄.免费网址| 久久久久久亚洲AV无码专区| 毛片A级毛片免费播放| 中文字幕在线免费播放| 亚洲国产高清在线精品一区| 亚洲成A人片在线观看中文| 91精品免费观看| 免费人人潮人人爽一区二区| 久久精品a亚洲国产v高清不卡 |