重构条件
Refactoring conditionals
我必须根据某些条件输出文本,如何重构它以使其易于理解和维护?
如果最好的选择是用状态替换,我需要为每个枚举组合创建一个 class?
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();
}
这是一个完美的例子,说明 State 模式有助于管理代码的复杂性,特别是如果您将来要添加其他 LicensingOption 和 CalcType。
This pattern is used in computer programming to encapsulate varying behavior for the same object based on its internal state. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements and thus improve maintainability.
我在下面附上了针对您的案例的状态模式实施示例,但请注意,您的代码示例很难真正给您好的建议(printW1
,printHeaderZ
和 printHeaderA
并没有真正给我那么多关于你的域的信息),但我尽力给你一些与你提供的代码等效的东西。您可能希望将某些行为从 CalcType 移至 LicesingOption,因为我不清楚这两种状态如何在您的应用程序中相互交互。
配置
// Whatever way you decide to get that configuration
public CalcType calcType = Config.CalcTypen
public LicensingOption license = Config.LicensingOption
计算类型类
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();
}
}
许可选项类
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++ 中的默认值)。
我必须根据某些条件输出文本,如何重构它以使其易于理解和维护?
如果最好的选择是用状态替换,我需要为每个枚举组合创建一个 class?
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();
}
这是一个完美的例子,说明 State 模式有助于管理代码的复杂性,特别是如果您将来要添加其他 LicensingOption 和 CalcType。
This pattern is used in computer programming to encapsulate varying behavior for the same object based on its internal state. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements and thus improve maintainability.
我在下面附上了针对您的案例的状态模式实施示例,但请注意,您的代码示例很难真正给您好的建议(printW1
,printHeaderZ
和 printHeaderA
并没有真正给我那么多关于你的域的信息),但我尽力给你一些与你提供的代码等效的东西。您可能希望将某些行为从 CalcType 移至 LicesingOption,因为我不清楚这两种状态如何在您的应用程序中相互交互。
配置
// Whatever way you decide to get that configuration
public CalcType calcType = Config.CalcTypen
public LicensingOption license = Config.LicensingOption
计算类型类
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();
}
}
许可选项类
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++ 中的默认值)。