Вы уже несколько часов работаете над какой-то неподдающейся задачей, а решения все не видно. Вы встаете, чтобы размять ноги, или направляетесь к автомату по продаже напитков, а на обратном пути ответ вдруг становится очевиден.
Случалось ли с вами такое? Приходилось ли вам задумываться, почему так происходит? Все дело в том, что, когда вы пишете код, активна логическая часть вашего мозга, а творческая отключена. Она никак не сможет себя проявить, пока логическая сторона не сделает перерыв в работе.
Вот вам пример из жизни. Я причесывал кое-какой старый код и наткнулся на «занятный» метод. Он предназначался для проверки правильности формата времени в строке вида 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;
}
Тот же самый код появлялся еще дважды с соответствующими изменениями в смещении символов и в значении верхней границы, чтобы проверить правильность минут и секунд. Заканчивался метод следующими строками, проверяющими AM и PM:
if (!time.substring(9, 11). equals("AM") &
!time.substring(9, 11). equals("PM")) {
return false;
}
Если ни одно из этого ряда условий не оказывалось ложным (при этом возвращается false), метод возвращал true.
Если приведенный код кажется слишком многословным и трудным для понимания, не волнуйтесь. Мне тоже так показалось, и я решил, что нашел код, который стоит подчистить. Я переработал его и написал несколько модульных тестов, чтобы проверить, по-прежнему ли правильно работает новый код.
Закончив работу, я остался доволен результатами. Новый вариант легко читался, был вдвое меньшего размера и точнее, поскольку прежний код проверял только верхнюю границу часов, минут и секунд.
Когда я собирался на работу на следующий день, меня посетила идея: а почему бы не проверить правильность строки с помощью регулярного выражения? Через несколько минут у меня была рабочая реализация, состоящая всего из одной строки кода:
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)");
}
Смысл не в том, что в итоге мне удалось заменить 30 с лишним строк кода одной, а в том, что пока я не отошел от компьютера, мне казалось, что мой первый вариант был лучшим решением задачи.
Поэтому, когда вы в следующий раз столкнетесь с неподатливой задачей, сделайте себе одолжение. По-настоящему разобравшись в сути проблемы, займитесь чем-то, что включит творческую часть вашего мозга: нарисуйте схему проблемы на бумаге, послушайте музыку или просто выйдите из дома. Иногда лучшее, что вы можете сделать, чтобы решить задачу, — это бросить мышь и отойти от клавиатуры.