2015-09-25 34 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++)。