Уроки извлеченные из разработки ПО.

dsc_0566

Данный пост является переводом замечательной статьи Хенрика Варне (Henrik Warne) “Lessons Learned in Software Development“. Как по мне – это отличный must-do список для каждого программиста. Так как статья и перевод – для программистов, я позволил себе использовать такие слова как “баги”, “фиксить”, “дэплой”, “репорты” и т.д.

Вот список моих эвристик и правил для разработки программного обеспечения, которые помогали мне много лет:

РАЗРАБОТКА.

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

Мне нравится цитата Джона Галла (John Gall): “Сложная система, которая работает – зачастую основана на простой, которая работала”.

2. Изменяйте только одну вещь. Когда во время разработки падает какой-то тест или фича перестает работать, гораздо проще найти проблему, если менялась только одна вещь. Другими словами, делайте короткие итерации. Делайте что-то одно, убеждайтесь что оно работает, и повторяйте это снова. Это существенно влияет на количество коммитов. Если вам нужно провести рефакторинг перед расширением функционала, сначала закомитьте рефакторинг, а уже потом сделайте комит для новой фичи.

3. Добавляйте логирование и обработку ошибок заранее. Первое, что я делаю при разработке новой системы – это добавление логирования и обработки ошибок, это очень полезно с самого начала. В любой программе, размер которой больше чем несколько строк кода, вам нужен способ понимать, что в ней происходит. Возможно, не тогда когда она работает как надо, но как только что-то идет не так, вы просто обязаны знать что случилось. То же касается и обработки ошибок – ошибки и исключения (exceptions) бывают и на самом старте разработки, чем раньше вы их выявите – тем лучше.

4. Все новые строки должны выполниться хотя бы раз. Перед тем как закончить фичу, вы должны ее протестить. В противном случае, как вы узнаете что она работает и выполняет то что должна? Зачастую, самый лучший способ – это автоматические тесты, но не всегда. Без разницы как, но каждая новая строчка кода должна хоть раз выполниться.

Иногда бывает очень трудно достичь нужных условий. К счастью, есть пару уловок. К примеру, обработку ошибок во время запроса к БД можно проверить вызвав таблицу с не правильным именем. Или “развернув” if-statement, можно проверить какой-то редкий кейс, что бы удостовериться, что код выполняется и делает то, что должен.

Иногда я вижу баги, которые говорят о том, что код никогда не запускался разработчиком. Этот код может выглядеть хорошо на code-review, но по-прежнему не работать. Всегда запуская ваш код, вы избежите подобных неловких ситуаций.

5. Тестируйте части перед тестом “в целом”. Хорошо протестированные части сохранят вам время. Зачастую бывают проблемы с интеграцией разный частей, к примеру, не соответствие или не понимание интерфейса между модулями. Если вы можете гарантировать, что части работают как должны, вам будет гораздо легче справиться с проблемами интеграции.

6. Все занимает больше времени, чем вы думаете. Особенно в программирование. Очень сложно оценить сколько времени займет фича, даже если все идет гладко. Во время разработки, вполне обычно встретиться с неожиданными проблемами: простой мердж приводит к трудноуловимому багу, обновление фреймворка означает изменение некоторых функций, или вызовы API не работают как должны.

Я думаю, что в Законе Хофстэдтера (Hofstadter Law) есть много правды: “Все занимает больше времени, чем вы ожидаете. Даже учитывая Закон Хофстэдтера”.

7. Сначала разберитесь в существующем коде. Большинство задач требует изменений в существующем коде. Даже если это новый функционал, то он должен будет интегрироваться в существующую программу. И до того как интегрировать, вам нужно разобраться в текущем коде. В противном случае вы можете случайно что-то сломать. Это означает, что читать код – так же важно как и писать. Также это причина, по которой небольшие изменения могут занимать много времени – вам нужно понимать контекст, в котором делать изменения.

8. Читайте и запускайте. К счастью, есть еще 2 способа для понимания кода. Вы можете прочитать код и можете его запустить. Выполнение кода может быть очень полезным в выяснении его функций. Убедитесь, что делаете оба метода.

УСТРАНЕНИЕ НЕПОЛАДОК.

9. Баги будут всегда. Я не люблю подходы в разработке ПО, которые гласят “сделайте правильно с первого раза”. Не важно сколько усилий вы приложите: всегда будут баги (определение бага в значительной степени – это “мы об этом не думали”). Гораздо лучший подход – держать систему в таком состоянии, что позволит быстро устранить проблемы, пофиксить баги и задэплоить изменения.

10. Решайте проблемы в отзывах. Каждый разработчик должен тратить часть своего времени на обработку репортов от пользователей и устранение неполадок. Это даст вам гораздо больше понимания того, что хотят сделать пользователи, как используется система, как сложно или легко устранять неполадки, хорошо ли эта система спроектирована. Также это очень хороший способ быть ответственным за то, что вы разрабатываете. Не упускайте все эти преимущества.

11. Повторяйте неполадку. Первый шаг в решении проблемы – это воспроизвести баг. Таким образом вы можете быть уверены, что после фикса проблема исчезнет. Это простое правило позволяет убедиться что вы не считаете проблемой то, что ею на самом деле не является и то что решение действительно делает то, что должно.

12. Устраняйте известные ошибки, потом смотрите что осталось. Иногда существует несколько проблем, о которых вам известно. Разные баги могут взаимодействовать друг с другом и порождать неожиданное поведение. Вместо того, что бы пытаться разобраться что происходит в этих случаях, исправьте все известные проблемы и тогда проверьте какие симптомы остались.

13. Считайте, что совпадений не существует. При тестировании и решении проблем, никогда не верьте в совпадения. Вы изменили значение таймера и теперь система чаще перезагружается. Не совпадение. Был добавлен новый функционал и не связанная фича стала медленней? Не совпадение. Вместо этого, изучайте.

Krivoblotsky: В моей практике я использую выражение “мистика”. Бывают моменты, когда код работает не так как должен. Все очевидно как Hello World, но все-равно что-то не так. Часы дэбага ни к чему не приводят. Начинаешь обвинять потустороннюю силу и берешь бубен, но потом замечаешь очевидные строки кода, которые во всем виноваты. Бывало? Я для себя отметил: “Мистики не бывает”.

14. Находите закономерности в таймстэмпах. При устранении неполадок, используйте таймстэмпы событий. Смотрите за каждым шагом. К примеру, если система перегрузилась и запрос был отправлен примерно за 3000 миллисекунд до этого, возможно проблема в таймере, который вызвал действие, которое в свою очередь привело к перезагрузке.

ВЗАИМОДЕЙСТВИЕ

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

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

17. Спрашивайте. Чтение и выполнение кода – очень полезно для понимания что он делает и как. Но если у вас есть возможность спросить кого-то осведомленного (возможно автора), используйте ее. Перспектива задать нужные вопросы и получить ответы может дать вам информацию за считанные минуты, в то время как вы бы потратили на это дни.

18. Упоминайте участников. Упоминайте участников где должны. Говорите: “Маркус предложил эту идею” (если это действительно он), вместо “мы попробовали”. Всегда упоминайте тех, кто помогал и делал вклад.

РАЗНОЕ

19. Пробуйте. Если вы не уверены как работают фичи того или иного языка, гораздо проще написать простенькую программку, которая покажет принцип работы. Такой же подход работает при тестировании системы, которую разрабатываете. Что случится, если я установлю этот параметр в “-1″? Что произойдет, если этот сервис не запущен, когда я перезагружаю систему? Исследуйте как это работает. Такого рода “возня” часто выявляет баги и в то же время углубляет ваши знания как системы работает.

Krivoblotsky: Анекдот в тему.

20. “Переспите с этим”. Если вы работаете над сложной задачей, постарайтесь выспаться перед принятием решений. Тогда ваше подсознание будет работать над реализацией, даже если вы активно над ним не думаете. Как результат, решение может быть очевидным на следующий день.

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

22. Учитесь. Одной из отличных штук в разработке ПО – это то, что всегда есть место учиться и узнавать новое. Попробуйте разные языки программирования и инструменты, читайте книги по разработке, запишитесь на курсы (в оригинале MOOC). Небольшие улучшения добавят существенную разницу в ваших знаниях и умениях.

Все права на контент принадлежат их авторам.
All rights belong to their respective owners.
Original article: http://henrikwarne.com/2015/04/16/lessons-learned-in-software-development/

Google+3LinkedIn16Twitter0Facebook0

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>