2015-09-25 61 views
1

我必須輸出基於某些條件的文本,我該如何重構這個以清楚理解和維護?重構條件

如果最好的選擇是用狀態替換,我需要爲每個枚舉組合創建一個類?

public enum CalcType {A, B, C, D} 
public enum LicensingOption {HOME, PRO, ULTIMATE} 

public void printHeader() { 
    switch (calc) { 
     case A: 
      printHeaderX(); 
      break; 
     case B: 
      printHeaderY(); 
      break; 
     default: 
      printHeaderByLicensingOption(); 
    } 
} 

public void printHeaderByLicensingOption() { 
    switch (license) { 
     case PRO: 
      printHeaderW(); 
      break; 
     case HOME: 
      printHeaderZ(); 
      break; 
     case ULTIMATE: 
      printHeaderA(); 
      break; 
    } 
} 

public void printFooter() { 
    if (calc.equals(CalcType.A)) 
     printFooterX(); 
    else 
     printFooterByLicensingOption(); 
} 

public void printFooterByLicensingOption() { 
    switch (license){ 
     case PRO: 
      printFooterW(); 
      break; 
     case HOME: 
      printFooterZ(); 
      break; 
     case ULTIMATE: 
      printFooterA(); 
      break; 
    } 
} 

public void printFooterW(){ 
    if (calc.equals(CalcType.B)) 
     printW1(); 
    else 
     printW2(); 
} 
+0

您可以將許可證轉換爲虛擬對象,並根據許可選項將其實例化爲不同的子類。然後每個子類都可以確切地知道要打印什麼,與其類型相對應。每個許可證可能會限制它允許應用程序執行的操作;那麼每個子類都會包含一些不重要但有用的謂語,「我是否許可做X?」。 –

回答

0

這是在State模式將幫助管理你的代碼的複雜性,特別是如果你要添加其他LicensingOption和CalcTypes在未來的一個很好的例子。

該模式用於計算機編程,以基於其內部狀態封裝同一對象的變化行爲。這可以成爲一種更簡潔的方式,讓對象在運行時改變其行爲,而無需訴諸龐大的單一條件語句,從而提高可維護性。

我已經把它貼下面的情況下,國家模式的實現的實例,但請注意,這是很難從你的代碼示例,真正給你很好的建議(printW1printHeaderZprintHeaderA不真的給了我很多關於你的域名的信息),但我盡我所能給你一些與你提供的代碼相同的東西。您可能希望將一些行爲從CalcType移動到LicesingOption,因爲我不清楚這兩個狀態在您的應用程序中如何相互作用。

配置

// Whatever way you decide to get that configuration 
public CalcType calcType = Config.CalcTypen 
public LicensingOption license = Config.LicensingOption 

CalcType類

abstract class CalcType { 
    public void printHeader() { 
     // Default behavior of printHeader() is printHeaderByLicensingOption(); 
     // except for CalcTypeA and CalcTypeB, so we are going to redefine them in CalcTypeA and CalcTypeB. 
     license.printHeaderByLicensingOption() 
    } 

    public void printFooter() { 
     // Default behavior of printFooter() is printFooterByLicensingOption(); 
     // except for CalcTypeA, so we are going to redefine it in CalcTypeA. 
     license.printFooterByLicensingOption() 
    } 

    public void printFooterW() { 
     // Default behavior of printFooterW() is printW2(); 
     // except for CalcTypeB, so we are going to redefine it in CalcTypeB. 
     printW2(); 
    } 
} 

class CalcTypeA extends CalcType { 
    public void printHeader() { 
     printHeaderX() 
    } 

    public void printFooter() { 
     printFooterX() 
    } 
} 

class CalcTypeB extends CalcType { 
    public void printHeader() { 
     printHeaderY() 
    } 

    public void printFooterW() { 
     printW1(); 
    } 
} 

LicensingOption類

abstract class LicensingOption { 
    // Those methods all have very different behaviour and it's hard from you example to know if there is any "default". 
    // Assuming there is none, just declare them abstract and define them in subclasses only. 
    abstract public void printHeaderByLicensingOption(); 
    abstract public void printFooterByLicensingOption(); 
} 

class ProLicense { 
    public void printHeaderByLicensingOption() { 
     printHeaderW(); 
    } 

    public void printFooterByLicensingOption() { 
     calcType.printFooterW() 
    } 
} 

class HomeLicense { 
    public void printHeaderByLicensingOption() { 
     printHeaderZ(); 
    } 

    public void printFooterByLicensingOption() { 
     printFooterZ() 
    } 
} 

class UltimateLicense { 
    public void printHeaderByLicensingOption() { 
     printHeaderA(); 
    } 

    public void printFooterByLicensingOption() { 
     printFooterA() 
    } 
} 

注意:確保您聲明的函數是虛擬的(默認爲Java,而不是C++)。