重构条件

时间:2015-09-25 10:29:13

标签: if-statement switch-statement refactoring conditional

我要根据一些条件输出一个文本,如何重构这个以使其清楚地理解和维护?

如果最好的选项是用状态替换,我需要为每个枚举组合创建一个类吗?

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();
}

1 个答案:

答案 0 :(得分: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 ++)。