Development

Отойдите от клавиатуры

(В оригинале – Put the Mouse Down and Step Away from the Keyboard)

Вот уже несколько часов вы напряженно ищете решение весьма неприятной проблемы, но решение никак не находится. В какой-то момент вы все бросаете и идете размять ноги и выпить глоток кофе, а по пути назад вам вдруг приходит понимание того, как эту проблему можно решить.
Звучит знакомо, не так ли? Интересно, как это работает? А дело в том, что пока вы напряженно работаете, логическая часть вашего мозга активна, а интуитивная – нет. И это может продолжаться до тех пор, пока вы не дадите логической части отдохнуть.

Вот пример из жизни. Я подчищал старый код и наткнулся на «интересную» функцию. Функция должна была проверять, что в строке содержится правильное время в формате hh:mm:ss xx, где hh – часы, mm – минуты, ss – секунды, а xx это AM или PM.

Функция использовала следующий код для конвертации двух символов (значение часов) в число с последующей проверкой того, что значение лежит в нужном диапазоне:

try {
  Integer.parseInt(time.substring(0, 2));
} catch (Exception x) { 
  return false;
}
if (Integer.parseInt(time.substring(0, 2)) > 12) { 
  return false;
}

Подобный код повторялся еще два раза – для проверки минут и секунд. А завершался проверкой на АМ или РМ.

if (!time.substring(9, 11).equals("AM") & !time.substring(9, 11).equals("PM")) { 
  return false;
}

Если все проверки проходили, возвращалось true, если хотя бы одна не проходила, возвращалось false.
Если вам показалось, что приведенный код написан не лучшим образом, то не волнуйтесь, мне показалось то же самое. Я захотел переписать это, написав сначала несколько юнит-тестов, чтобы быть уверенным, что все работает.

После окончания рефакторинга я остался доволен. Новая версия была гораздо легче читаема, в два раза компактнее и лучше протестирована.
А когда я пришел на работу на следующее утро, в голове у меня вдруг возникла идея: «А почему бы не использовать регулярные выражения?» И после нескольких минут кодирования я получил работающую реализацию, уместившуюся в одну строчку:

public static boolean validateTime(String time) {
  return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)");
}

Мораль истории не в том, что я в конце концов заменил тридцать строк кода одной, а в том, что пока я не отошел от компьютера, я думал, что моя первая попытка была лучшим решением из всех возможных.

Так что когда в следующий раз вы столкнетесь с сложнорешаемой проблемой, помогите себе. Как только вы вникнете в проблему, сделайте что-то, что вовлечет интуитивную часть мозга – послушайте музыку, пройдитесь вокруг. Иногда лучшее, что вы можете сделать для решения проблемы – это отойти подальше от мышки и клавиатуры.

Автор оригинала – BurkHufnagel