Pull to refresh

Программисты-оптимисты

Reading time 5 min
Views 78K

Мы, программисты, — оптимисты. Это проявляется во всем цикле разработки ПО от оценки сроков до написания кода и внедрения. Как показывает моя практика, в разработке ПО законы Мерфи работают в 100% случаев. Несмотря на это, я раз за разом сталкиваюсь с «программистами-оптимистами».

Топ «оптимистичных» допущений:

Мы все еще можем выпустить релиз на этой неделе в пятницу в 17:48, хотя в коде есть ошибки

Нет, не можете. Кроме исправления ошибок, вам нужно:
  1. Смержить/запулить этот код (вы же не ведете разработку в ветке из которой публикуетесь в продакшн, правда?)
  2. Опубликовать код на тестовом стенде и протестировать, в том числе регрессию
  3. Проверить конфигурации, миграции БД
  4. Забекапить продакшн
  5. Опубликовать изменения
  6. Протестировать продакшн
  7. Откатиться, если что-то пошло не так

Даже если все происходит в автоматическом режиме, вам едва-ли хватит 12 минут до конца рабочего дня для того, чтоб закончить. Обычно такие выкладки производятся впопыхах и заканчиваются глупыми ляпами на продакшне, переработками по ночам и/или в выходные, откатами к предыдущему релизу и переносу выкладки, либо комбинацией этих пунктов.

Решение о релизе/выкладке можно принимать только после того, как код написан и протестирован. Точно знайте сколько времени занимает выкладка, бекап и откат к предыдущей версии в случае эпик фейла. Всегда закладывайте самый пессимистичный вариант: вы выложитесь и вам, по тем или иным причинам, придется откатиться. На текущем проекте мы автоматизировали все выкладки и бекапы. На выкладку требуется 10 минут, на восстановление из бекапа: 10 минут, на минимальное смоук-тестирование: 2 часа. Значит, для выкладки на продакшн, я закладываю 3 часа времени.

Это займет три дня. А за день сможешь? Ну, может, смогу

Не идите на поводу у менеджеров. Менеджер, даже с техническим бекграундом, не знает всей подноготной. То, что может казаться простым и быстрым менеджеру, на самом деле может занимать гораздо больше времени. Менеджер всегда оценивает только трудоемкость реализации новой фичи. Ваша задача настоять на том, что вам нужно время на рефакторинг, тестирование, выкладку. Идя на поводу у менеджмента, раз за разом вы будете откладывать технический долг, пока его не накопится столько, что вы не будете знать с какой стороны подойти к рефакторингу. Требования меняются, никто не может сразу писать идеальный код, не больше и не меньше, чем потребуется. Если вы чувствуете, что костыли в этом месте аукнутся днями и неделями в будущем, лучше потратить лишние несколько часов сейчас и сдать фичу чуть позже. Объясните это менеджеру на его языке: сейчас этот рефакторинг обойдется нам в 8 часов. А если мы вставим костыли, то через месяц наш технический долг будет стоить 56 часов. Менеджеры обычно хорошо считают, и без труда умножат количество часов на ваш рейт. Помните, что никто, кроме вас не знает код лучше, поэтому вы лучше знаете, как делать лучше с технической стороны. Подробно о прессинге менеджмента можно почитать в статье «Как две недели?!».

О, это очень глупый баг, сейчас я быстренько его поправлю и все заработает. Тест писать ни к чему

Нет, баг — это повод написать юнит-тест. Если он появился, значит, что вы пропустили это поведение и у вас дыра в «покрытии кода». Нашли баг? Добавьте юнит-тест/интеграционный тест/тест-кейс в тест-план. Это избавит от «бумерангов» — багов, возвращающихся снова и снова.

Это очень простая фича, можно даже не добавлять ее в таск-трекер. Сделаю так, требования ясны

Нет, требования, наверняка, сложнее, чем кажется на первый взгляд. Возможно, что новые требования будут конфликтовать с существующим поведением системы. Если вы не добавите таск в трекер, то в любой спорной ситуации окажитесь крайним. Самый худший вариант — устная договоренность. У людей очень короткая память. Все задачи должны ставиться только в письменном виде. Подробно об управлении требованиями я писал в статье «Specification By Example – BDD для прагматиков».

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

Нет, всегда тестируйте, в первую очередь на «целевом» окружении/железе. Любая эмуляция — лишь модель. В реальных условиях могут всплыть непредвиденные обстоятельства: другая версия ОС, другие права, другая мощность процессора, объем оперативной памяти, другие открытые порты. Все что угодно.

Эта проверка здесь ни к чему. Никому не придет в голову пользоваться программой таким образом

Лишних проверок не бывает. Именно для таких случаев придумали исключения(exceptions). Вы не поддерживаете какое-то поведение/сценарий? Выбросите NotSupportedException. Все будет предельно ясно. А вот хуже, чем NullReferenceException сложно что-то себе представить. Это не дает никакой информации человеку, поддерживающему ваш код. Он не обязан рыться в стек-трейсе и искать низкоуровневые ошибки. Всегда обрабатывайте низкоуровневые ошибки и используйте свои понятные исключения. В .NET у исключения есть свойство InnerException, которое поможет сохранить информацию о более низкоуровневой проблеме. Неплохо про exception handling в .NET написано в статье «Безопасная работа с исключениями в C#».

Эту ошибку можно обработать и сделать вид, что ничего не случилось

Пустые try-catch блоки обычно появляются, когда в требованиях к ПО появляются надежность и отказоустойчивость. Такое поведение эквивалентно заметанию мусора под ковер, чтобы никто не увидел. Если вам нужна отказоустойчивость, — предусмотрите аварийный перезапуск системы. Первое, что вы должны сделать — логировать исключение и сообщать разработчикам. Можно отправлять письма разработчикам в случае ошибок, можно использовать мессенджеры, вариантов масса. Самое худшее, что можно сделать, это проигнорировать ошибку, потому что вы не знаете к каким последствиям это приведет. Слово «исключение» выбрано не просто так. Это подчеркивает, что поведение не запланировано и не является нормальным.

Это не бага, это — фича, на тесте БД пустая, на продакшне все нормально будет

Нет и еще раз нет. Если данные обязаны быть в БД, то включите их в выкладку. Изменили конфигурацию? Добавьте трансформацию конфига. Если какой-то кейс не проверен, в 9 из 10 случаев в нем найдется ошибка. На таком стенде невозможно провести демонстрацию. «Здесь вылезает ошибка, но на боевом ее не будет» — звучит ужасно. Если по каким-то причиам невозможно настроить тестовый стенд идентично продакшну (финансовые операции, платные аккаунты, настройки безопасности и т.д.), пользуйтесь стабами (stub), эмуляторами и аналогичными тестовыми аккаунтами. Приближайте ваш тестовый стенд к продакшну настолько, насколько это возможно.

Я пофиксил/обновил, вроде работает

Никаких «вроде». Если на стенде была ошибка любого рода, проверьте, что после вашего фикса/обновления не сломалось ничего другого. Заведите минимальный чек-лист проверки работоспособности приложения после обновления, например: залогиниться, купить что-то посмотреть пару-тройку страниц. Это избавит тестировщиков и ваших коллег разработчиков от многократных обращений к вам: «слушай, в товарах эксепшн, а в новостях старая ошибка пропала, но новая появилась». Воспринимайте такую проверку как нечто само-собой разумеющееся, как элемент личной гигиены. Вы же не задумываетесь, почему чистите зубы и умываетесь каждый день.

Фиг знает в чем была проблема, я перезапустил, оно заработало

Никаких «фиг знает. Вы должны точно понимать и пресекать любые возможности падения программы. Если вы решаете проблему перезапуском, вы боритесь не с причиной, а со следствием. Эта проблема гарантированно будет повторяться в самый неподходящий момент. Вас будут будить среди ночи, чтобы вы в очередной раз перезапускали приложение, потому что оно «свалилось». Всегда решайте проблему полностью. Приложению нужен регулярный ребут? Настройте автоматический перезапуск, локализуйте проблему, добавьте таск и исправьте это. Очень хорошо о вреде «шапкозакидательства» написано в статье «Что плохого в работе на результат».

Выполнение вышеописанных рекомендаций требует самодисциплины. Соблюдать их чертовски сложно, но законы Мерфи не подводили меня ни разу. Каждый раз, когда я делаю исключение, случается что-то непредвиденное, экстраординарное и незапланированное. Каждый раз, когда не получается сдать работу качественно и в срок, я расстраиваюсь, поэтому я стараюсь никогда не отступать от этих правил. В результате, я гораздо оптимистичнее, чем раньше смотрю на разработку ПО в целом. Я знаю, что не существует «слишком сложных» задач. Существуют задачи требующие достаточно много времени для реализации. Надеюсь, что мой чек-лист будет полезен другим разработчикам.
Tags:
Hubs:
+105
Comments 87
Comments Comments 87

Articles