前面说过了函数要专注于做一件事,函数要么做什么事,要么回答什么事,二者不可兼得。
拆分执行与询问
举个栗子
public boolean set(String attribute, String value);
这个函数设置某个指定的属性,如果成功返回true,不存在返回false。这样就有了如下的代码
if(set(“username”, “unclebob”))…
对于作者来说,写出这些代码,自己当然是很清楚的,但是对于读者来说,这个就有两种可能的意思了,第一就是问username属性值是否之前已设置为unclebob,另一种就是在问username属性值是否成功设置为unclebob。
但是如果改为如下,意思就很明白了
if(attributeExists(“username”)){
setAttribute(“username”, “unclebob”);
}
使用异常替代返回错误码
还是两个例子对比
if (deletePage(page) == E_OK) {
if (registry.deleteReference(page.name) == E_OK) {
if (configKeys.deleteKey(page.name.makeKey()) == E_OK){
logger.log("page deleted");
} else {
logger.log("configKey not deleted");
}
} else {
logger.log("deleteReference from registry failed");
}
} else {
logger.log("delete failed");
return E_ERROR;
}
若用异常替代返回错误码,错误处理代码就能从主路径代码中分离出来得到简化
try {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
logger.log(e.getMessage());
}
抽离try/Catch代码块
错误处理就是一件事。
错误处理和正常流程不要混为一谈,最好将try/catch代码块的主题抽离出来,另外形成函数。
public void delete(Page page) {
try {
deletePageAndAllReferences(page);
} catch (Exception e) {
logError(e);
}
}
private void deletePageAndAllReferences(Page page) throws Exception {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e){
logger.log(e.getMessage));
}
不要重复自己
将代码中重复的部分抽离出来,做成一个函数。