2017-02-16 36 views
1

我已經繼承了一個需要重構的應用程序。以下是給我一些頭痛的問題。原來的源代碼有太多的開關情況如下所示:帶有太多開關的重構代碼

class Girl { 
    //... 
    void traditionalMakeUp() { 
     switch (type) { 
      case FRENCH: 
       frenchMakeUp(); 
       break; 
      case AFRICAN: 
       africanMakeUp; 
       break; 
      case NORWEGIAN: 
       norwegianMakeUp(); 
       ..... 

      case KOREAN: 
       koreanMakeUp(); 
       ..... 
     } 
    } 
} 

我試圖重構它是這樣的:

abstract class Girl { 
    //... 
    abstract void makeUp(); 
} 

class French extends Girl { 
    void makeUp() { 
     // makeUP 
    } 
} 
class African extends Girl { 
    void makeUp() { 
     // makeUP 
    } 
} 
class Norwegian extends Girl { 
    void makeUp() { 
     // makeUP 
    } 
} 

// Somewhere in client code 
girl.makeUp(); 

是否做了正確的方法是什麼?如果我的交換機中沒有20個以上的案例,那麼戰略模式會很好。

此外,我不願意添加20多個類來適應戰略設計模式。還有另一種重構它的好方法嗎?

+0

makeUp()方法的每個變體都有什麼作用? – Naros

+0

@Naros makeUp()因國籍而異。 makeUp()邏輯在挪威語中完全不同於makeUp()邏輯在法語中等等...... –

+0

轉換中的案例數量是多少固定或增長的可能性? 'makeUp()'方法的平均代碼行是多少?是依賴於其他類的'makeUp()'方法還是完全獨立的代碼? –

回答

1

有多種方法來重構這種情況。

繼承無疑是在這裏考慮的一種選擇。但是,根據層次結構的深度,以及是否需要在層次結構中創建助手類或中間類以共享通用代碼,我會考慮組合。

雖然#makeUp確實根據女孩的類型而有所不同,但也許存在語義上的相似之處,您可以在其中構建小單元的代碼(組件),然後您可以以類似組件的方式拼湊在一起。

+0

謝謝!我會試着看看作文。 –

1

看起來繼承是在這裏調用的,這取決於您的應用程序中存在的其他操作/開關Girl基於屬性type

如果這是唯一的開關,你可以做類似下面,

定義枚舉女孩與一個抽象方法 - 化妝(),然後執行該方法就在那裏爲枚舉類型。

public enum Girl { 

    FRENCH { 
     public void makeUp() { 
      Utility.frenchMakeUP(); 
     } 
    }, 

    AFRICAN { 
     public void makeUp() { 
      Utility.africanMakeUP(); 
     } 
    }, 

    NORWEGIAN { 
     public void makeUp() { 
      Utility.norwegianMakeUP(); 
     } 
    }, 

    KOREAN { 
     public void makeUp() { 
      Utility.koreanMakeUP(); 
     } 
    }; 

    public abstract void makeUp(); 

} 

Your Utility class看起來像這樣。

public class Utility { 

    public static void frenchMakeUP() { 

    } 

    public static void africanMakeUP() { 

    } 

    public static void norwegianMakeUP() { 

    } 

    public static void koreanMakeUP() { 

    } 

} 

客戶端代碼

Girl girl = Girl.FRENCH; 
girl.makeUp(); 

可以取決於有多少功能存在,以及如何共同的功能,即通話,Utility.koreanMakeUP()從與makeUp()結合還可以組織組織多個實用工具類。

0

我寧願爲女孩在這裏組成和化妝繼承。根據你的域名,法國女孩穿非洲化妝可能沒問題。讓一個女孩包含一個MakeUp類型的對象。

然後,我會做這樣的事情:

public class FrenchMakeUp extends MakeUp 
{ 
    @Override 
    public void apply(){...} 
} 

public class Girl 
{ 
    public void makeUp(MakeUp makeUp) 
    { 
     makeUp.apply(); 
    } 
} 

在客戶端代碼:

girl.makeUp(new FrenchMakeUp()); 

這是更接近你試圖重構,但它並沒有解決決策。也許你可以有一張地圖來幫助你選擇正確的化妝類型。