Исходный код
public String find(String request) {
String result="";
status.setState(Status.STATUS_IN_PROGRESS);
status.setMessage("search start");
buildTokens(request);
if (buildWords()) {
if (buildSynonyms()) {
if (buildValues()) {
if (buildProperties()) {
if (buildParameters()) {
result = buildCondition();
status.setParameters(newArrayList(parameters));
status.setState(Status.STATUS_SUCCESS);
status.setMessage("search done successfully");
} else {
status.setState(Status.STATUS_FAIL);
status.setMessage("can't build parameters");
}
} else {
status.setState(Status.STATUS_FAIL);
status.setMessage("can't build properties");
}
} else {
status.setState(Status.STATUS_FAIL);
status.setMessage("can't build values");
}
} else {
status.setState(Status.STATUS_FAIL);
status.setMessage("can't build synonyms");
}
} else {
status.setState(Status.STATUS_FAIL);
status.setMessage("can't build words");
}
return result;
}
Как можно отрефакторить исходный код
В общем случае я не люблю операторы выхода внутри тела функции, но тут как раз тот случай, когда они подходят лучше всего (думаю, как раз для таких случаев их и придумали).
Применить их позволяет то обстоятельство, что код метода максимально чистый: он не содержит никаких других знаний, кроме круга ответственных за сборку результата, последовательности их вызовов и отслеживание успешности процесса.
Для большей красоты я бы добавил классу состояния специфические методы по количеству состояний, чтобы уменьшить общее количество вызовов.
public String find(String request) {
String result="";
status.setInProgress("search start");
buildTokens(request);
if (!buildWords()) {
status.setFail("can't build words");
return result;
}
if (!buildSynonyms()) {
status.setMessage("can't build synonyms");
return result;
}
if (!buildValues()) {
status.setMessage("can't build values");
return result;
}
if (!buildProperties()) {
status.setMessage("can't build properties");
return result;
}
if (!buildParameters()) {
status.setMessage("can't build parameters");
return result;
}
result = buildCondition();
status.setParameters(newArrayList(parameters));
status.setSuccess("search done successfully");
return result;
}
Здесь намеренно выбран return result
в каждой ошибочной ветке, потому что так проще будет поменять дефолтное возвращаемое значение метода в случае ошибки.
Этот рефакторинг касается только лесенки операторов if
, однако же здесь больше сомнений вызывает выбранный способ обработки ошибок.
Я бы всё-таки посмотрел в сторону исключений, и бросать их должны сами методы buildWords
, buildSynonyms
и т.д.