Думай лучше, пиши лучше код

Однажды мне пришлось отлаживать приложение, которое возвращало 404 NOT FOUND, хотя должно было возвращать 200 OK. Причиной была условная логика, где во многих ситуацияхи условие if, и elseif всегда были истинными. По этой причине оценивалось только первое условие, поэтому была выбрана только первая ветвь. Всегда. Программа была закорочена. Обнаружение этой ошибки заставило меня задуматься над своим мышлением при написании условной логики, которая является ключевой частью того, как код принимает решения.

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

Чтобы сделать еще один шаг, потребуется время, чтобы подумать о «метаданных», связанных с каждым условием. Я придумал несколько вопросов, которые задаю себе всякий раз, когда пишу условную логику, чтобы тщательно все обдумать и избежать ошибок. Возможно, вам они тоже пригодятся.

# 1 Почему это условие верно?

Этот вопрос не является пустой тратой времени. Иногда, поработав какое-то время над кодом, у нас появляется туннельное зрение, и мы не читаем его внимательно. Или, может быть, логика в другом месте кода была изменена, но условие не было обновлено. Найдите минутку, чтобы сформулировать, что делает условие истинным, например  — «это условие будет истинным, когда массив X не пуст.

# 2 Знаю ли я все обстоятельства, которые сделают это правдой?

Этот вопрос является продолжением № 1. Думать о том, когда нам нужно, чтобы определенные условия были истинными, важно, потому что программа будет пытаться делать точно так, как ей сказано. Вы должны обдумать все возможные сценарии и дать соответствующие инструкции.

# 3 Будет ли это условие всегда истинным (или ложным), и это то, что я имею в виду?

Если условие всегда истинно (или ложно), код всегда будет следовать одному и тому же пути. Если это не предусмотрено, то это плохо.

#4 Если бы мне нужно было написать условие, подразумеваемое else,что это будет?

Остальное — это расплывчатая территория, и я иногда ловлю себя на том, что забываю подумать о том, что это на самом деле означает. Найдите минутку, чтобы составить предложение, описывающее, какие условия перекрываются словом else.

# 5 Является ли условие, требуемое конкретной ветвью, взаимоисключающим с другими условиями?

Часто, когда мы создаем ветки в коде, мы хотим, чтобы условия были взаимоисключающими, чтобы поток программы шел в правильном направлении для конкретной ситуации. Если условия взаимоисключающие, то порядок их перечисления не имеет значения. Но если это не так, вы можете закоротить свой код! Если два условия выполняются одновременно, то то, что указано первым, будет определять поток программы.

# 6 Какова «история», которую рассказывает эта условная логика как для счастливого, так и для несчастливого конца?

По сути, это синтез вопросов 1–5. Пройдитесь по каждому из возможных путей программы (еще лучше, если вы скажете это вслух про себя). НЕ делайте предположений, основанных на частях кода, которые вы просматривали сотни раз. Прочтите код. Заполните детали условной истории, например «X является целым числом, возвращаемым функцией № 1, и входит в условную структуру, где это приведет к тому, что первое условие будет истинным, а затем будет вызвана функция 2…». Проверьте, является ли история кодом. рассказ имеет окончание, которое вы ожидаете.

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

PS — слон в комнате пишет лучшие юнит-тесты. Прочтите мой краткий рассказ здесь, чтобы получить хороший совет.