我建立了我的Android设备中的HTTP服务器。
我使用的是大量的if-else语句来处理不同的充请求。
我将与其他人供以后使用来分享我的代码,我将不得不作出它清晰越好。 现在,我甚至不能看我的轻松代码。
我认为这个问题来自于一个类使用了大量if-else语句的。 例如。
if(purpose.equals("readProfile"){
.....
}
else if(purpose.equals("writeProfile"){
.....
}
....
我想他们的类别进行分类,并根据其类别排序的条件。 但不是很多legebility的提高。 然后我试着写短评盈的各条件。 但是,这变得更加混乱。
有什么可以做,以增加条件语句的可读性?
作为Luiggi门多萨说,这是一个随访前一个问题 ...
如果您使用的是Java 7,您可以使用字符串的switch-case语句
//month is a String
switch (month.toLowerCase()) {
case "january":
monthNumber = 1;
break;
//partsleft out for sake of brevity ..
default:
monthNumber = 0;
break;
}
(从Oracle Java教程摘录,上文引用的)。
重构
然而,这个巨大的if-else只是问题的一部分。 由于这似乎是随着时间而长势的结构,我建议彻底的重构,用什么在我看来,是一个策略模式 。 你应该:
制定涵盖所有用例的边界的界面:
interface MyStrategy {
void execute(MyInputContext input, MyOutputContext output);
}
(使用MyInputContext和MyOutputContext只是一种方法空洞的方法,这仅仅是一个例子,但处理有响应的请求,这是有道理的,就像Servlet的工作原理)
重构的大if-else语句的内容到这个接口的情况下(这将是策略):
//VERY simplified...
class ReadProfileStrategy implements MyStrategy {
void execute(MyInputContext input, MyOutputContext output) {
//do the stuff that was in the if-else block in the "readProfile" part
}
}
//... at the branching part:
MyInputContext input; //build this here
MyOutputContext output; //build this here
switch (purpose) {
case "readProfile":
// no need to always instantiate this, it should be stateless...
new ReadProfileStrategy().execute();
break;
//... left out for sake of brevity
}
重构步骤2
如果做到这一点,您可以将字符串ID添加到界面,与实例本身,并摆脱的if-else或switch语句完全,你可以创造出通过IOC容器填充的地图(如),是最新的,并且完全灵活。
class ReadProfileStrategy implements MyStrategy {
String getID() {
return "readProfile";
}
void execute(MyInputContext input, MyOutputContext output) {
//do the stuff that was in the if-else block in the "readProfile" part
}
}
在上课的时候请求被处理
private final Map<String, MyStrategy> strategyMap; //fill the map using your favorite approach, like using Spring application context, using the getCode() to provide the key of the map
在处理逻辑:
MyStrategy strategy = strategyMap.get(purpose);
if(strategy!=null) {
strategy.execute();
}
else {
//handle error here
}
这可能是超出了范围,但只是一个观察
尝试使用
if("readProfile".equals(purpose){}
而不是
if(purpose.equals("readProfile"){}
这将有助于避免空品特例外
枚举可以帮助 - 你也可以将它们添加功能。
public void test(String purpose) {
if (purpose.equals("readProfile")) {
// Read.
} else if (purpose.equals("writeProfile")) {
// Write.
}
}
enum Purpose {
readProfile {
@Override
void doIt() {
// Read.
}
},
writeProfile {
@Override
void doIt() {
// Write.
}
};
abstract void doIt();
}
public void test2(String purpose) {
Purpose.valueOf(purpose).doIt();
}
您可以尝试使用某种操作接口与每个块的实现,并预装了此操作的具体实现的地图。
interface Action {
void execute();
}
Map<String, Action> actions = new HashMap<>();
actions.put("readProfile", new Action() { ... });
actions.put("writeProfile", new Action() { ... });
actionMap.get(purpose).execute();
这会降低你的圈复杂度为好。 当然,你应该预装地图只有一次。
好吧,如果这是有道理里面的if-else条件代码分离到另一个类,或者是用工厂模式。 也使所有分离类实现公共接口(例如: MyActivity.class
)用方法如execute()
厂决定什么对象( ReadProfile.class
, WriteProfile.class
等)的基础上,你把这个字符串被创建,然后调用execute()
方法。
MyActivity obj = MyFactory.createMyActivity(String)
obj.execute(...);