Dav*_*vid 35 java refactoring if-statement
我有一个带有千行if/else逻辑方法的java类,如下所示:
if (userType == "admin") {
if (age > 12) {
if (location == "USA") {
// do stuff
} else if (location == "Mexico") {
// do something slightly different than the US case
}
} else if (age < 12 && age > 4) {
if (location == "USA") {
// do something slightly different than the age > 12 US case
} else if (location == "Mexico") {
// do something slightly different
}
}
} else if (userType == "student") {
if (age > 12) {
if (location == "USA") {
// do stuff
} else if (location == "Mexico") {
// do something slightly different than the US case
}
} else if (age < 12 && age > 4) {
if (location == "USA") {
// do something slightly different than the age > 12 US case
} else if (location == "Mexico") {
// do something slightly different
}
}
Run Code Online (Sandbox Code Playgroud)
我应该如何将其重构为更易于管理的内容?
Pét*_*rök 26
您应该使用可能在枚举中实现的策略,例如:
enum UserType {
ADMIN() {
public void doStuff() {
// do stuff the Admin way
}
},
STUDENT {
public void doStuff() {
// do stuff the Student way
}
};
public abstract void doStuff();
}
Run Code Online (Sandbox Code Playgroud)
由于代码中每个最外层if
分支中的代码结构看起来几乎相同,因此在下一步重构中,您可能希望使用模板方法分解该重复.或者,您也可以将位置(可能还有年龄)转换为策略.
更新:在Java4中,您可以手动实现类型安全枚举,并使用普通的旧子类来实现不同的策略.
Bil*_*ard 12
我要对这段代码做的第一件事是创建类型,Admin
并且Student
两者都继承自基类型User
.这些类应该有一个doStuff()
隐藏此逻辑其余部分的方法.
根据经验,只要你发现自己打开类型,就可以使用多态.
成千上万的?也许你需要一个规则引擎.Drools可能是一个可行的选择.
或者一个命令模式,它封装了每个案例的所有"做一些稍微不同"的逻辑.将每个命令存储在地图中,并将年龄,位置和其他因素作为关键字连接起来.查找命令,执行它,你就完成了.干净整洁.
Map可以存储为配置并在启动时读入.您可以通过添加新类和重新配置来添加新逻辑.
首先 - 使用userType和location的枚举 - 然后你可以使用switch语句(提高可读性)
第二 - 使用更多方法.
例:
switch (userType) {
case Admin: handleAdmin(); break;
case Student: handleStudent(); break;
}
Run Code Online (Sandbox Code Playgroud)
然后
private void handleAdmin() {
switch (location) {
case USA: handleAdminInUSA(); break;
case Mexico: handleAdminInMexico(); break;
}
}
Run Code Online (Sandbox Code Playgroud)
此外,识别重复的代码并将其放入额外的方法中.
编辑
如果有人强迫您在没有枚举的情况下编写Java代码(就像您被迫使用Java 1.4.2一样),请使用'final static'而不是enums或执行以下操作:
if (isAdmin(userType)) {
handleAdmin(location, age);
} else if (isStudent(userType)) {
handleStudent(location, age));
}
//...
private void handleAdmin(String location, int age) {
if (isUSA(location)) {
handleAdminInUSA(age);
} else if (isUSA(location)) {
handleAdminInMexico(age);
}
}
//...
private void handleAdminInUSA(int age) {
if (isOldEnough(age)) {
handleAdminInUSAOldEnough();
} else if (isChild(age)) {
handleChildishAdminInUSA(); // ;-)
} //...
}
Run Code Online (Sandbox Code Playgroud)