Java 提高条件语句的可读性
我正在为我的android设备构建一个HTTP服务器 我使用了很多IF-ELSE语句来处理不同的请求 由于我将与其他人共享我的代码以供日后使用,因此我必须使其尽可能清晰易读。现在,我甚至不能轻松地阅读我的代码 我认为问题来自于在一个类中使用大量IF-ELSE语句。 比如说Java 提高条件语句的可读性,java,android,readability,code-readability,Java,Android,Readability,Code Readability,我正在为我的android设备构建一个HTTP服务器 我使用了很多IF-ELSE语句来处理不同的请求 由于我将与其他人共享我的代码以供日后使用,因此我必须使其尽可能清晰易读。现在,我甚至不能轻松地阅读我的代码 我认为问题来自于在一个类中使用大量IF-ELSE语句。 比如说 if(purpose.equals("readProfile"){ ..... } else if(purpose.equals("writeProfile"){ ..... } .... 我试着
if(purpose.equals("readProfile"){
.....
}
else if(purpose.equals("writeProfile"){
.....
}
....
我试着将它们分类,并根据它们的类别对条件进行排序。但法律效力并没有得到很大改善。
然后我试着在每种情况下写简短的评论。但这让事情变得更糟
如何提高条件语句的易读性?这可能超出范围,但只是一个观察 试用
if(“readProfile”.equals(purpose){}
代替
if(purpose.equals(“readProfile”){}
这将有助于避免空品特异常这可能超出范围,但只是一个观察 试用
if(“readProfile”.equals(purpose){}
代替
if(purpose.equals(“readProfile”){}
这将有助于避免空品特异常如上所述,这是对
如果您使用的是Java7,则可以使用
(摘自上述Oracle Java教程。)
重构
然而,这个巨大的if-else只是问题的一部分。由于这似乎是一个随着时间的推移而不断增长的结构,我建议进行彻底的重构,并使用在我看来是一个好方法。你应该:
制定一个涵盖所有用例边界的接口:
interface MyStrategy {
void execute(MyInputContext input, MyOutputContext output);
}
(使用带有MyInputContext和MyOutputContext的void方法只是一种方法,这只是一个示例,但要处理有响应的请求,这是有意义的,就像servlet的工作方式一样)
将大型IF-ELSE语句的内容重构到此接口的实例中(以下是策略):
重构步骤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
如上所述,这是对
如果您使用的是Java7,则可以使用
(摘自上述Oracle Java教程。)
重构
然而,这个巨大的if-else只是问题的一部分。由于这似乎是一个随着时间的推移而不断增长的结构,我建议进行彻底的重构,并使用在我看来是一个好方法。你应该:
制定一个涵盖所有用例边界的接口:
interface MyStrategy {
void execute(MyInputContext input, MyOutputContext output);
}
(使用带有MyInputContext和MyOutputContext的void方法只是一种方法,这只是一个示例,但要处理有响应的请求,这是有意义的,就像servlet的工作方式一样)
将大型IF-ELSE语句的内容重构到此接口的实例中(以下是策略):
重构步骤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
您可以尝试对每个块的实现使用某种类型的操作接口,并用此操作的具体实现预加载一个映射
interface Action {
void execute();
}
Map<String, Action> actions = new HashMap<>();
actions.put("readProfile", new Action() { ... });
actions.put("writeProfile", new Action() { ... });
actionMap.get(purpose).execute();
接口动作{
void execute();
}
Map actions=newhashmap();
actions.put(“readProfile”,newaction(){…});
actions.put(“writeProfile”,newaction(){…});
get(purpose.execute();
这也将降低圈复杂度。当然,您应该只预加载贴图一次。您可以尝试使用某种类型的操作界面来实现每个块,并使用此操作的具体实现预加载贴图
interface Action {
void execute();
}
Map<String, Action> actions = new HashMap<>();
actions.put("readProfile", new Action() { ... });
actions.put("writeProfile", new Action() { ... });
actionMap.get(purpose).execute();
接口动作{
void execute();
}
Map actions=newhashmap();
actions.put(“readProfile”,newaction(){…});
actions.put(“writeProfile”,newaction(){…});
get(purpose.execute();
这也将降低圈复杂度。当然,您应该只预加载地图一次。枚举可以帮助您,您还可以向它们添加功能
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();
}
枚举可以帮助您,您还可以为它们添加功能
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();
}
好的,如果将If-else条件中的代码分离到另一个类是有意义的,也许可以使用工厂模式。还可以使用
execute()
等方法使所有分离的类实现公共接口(例如:MyActivity.class
)
工厂根据传递的字符串决定必须创建的对象(ReadProfile.class
,WriteProfile.class
等),然后调用execute()
方法
MyActivity obj = MyFactory.createMyActivity(String)
obj.execute(...);
好的,如果将If-else条件中的代码分离到另一个类是有意义的,也许可以使用工厂模式。还可以使用
execute()
等方法使所有分离的类实现公共接口(例如:MyActivity.class
)
工厂根据传递的字符串决定必须创建的对象(ReadProfile.class
,WriteProfile.class
等),然后调用execute()
方法
MyActivity obj = MyFactory.createMyActivity(String)
obj.execute(...);
为一组请求定义类似的行为,并创建特定的接口,这些接口将保存这些请求的通用方法,类实现将保存这些请求的特定业务逻辑。您可以创建一个工厂,该工厂将接收例如目的(
“readProfile”
,“writeProfile”
)并将返回界面,这样您就不必为这些if-else
语句操心了