Как начинающему разработчику избежать безудержной отладки, красных глаз и испорченного настроения

Kate

Administrator
Команда форума
Привет! Я техлид и коуч Binary Studio, поэтому много работаю со студентами и начинающими разработчиками. Все они допускают похожие ошибки, которые замедляют профессиональное развитие. В этом материале я собрал несколько советов, как избежать шишек джуну. Эта статья будет полезна в первую очередь тем, кто уже пробовал писать коммерческие проекты, но еще не имеет достаточно опыта. Я старался концентрироваться исключительно на практических примерах, избегая лишних рассуждений. Весь материал базируется на моем личном опыте, поэтому, если вам есть что дополнить, пишите в комментариях.

Используй готовые инструменты​

Если бы я мог вернуться в то время, когда только начинал свою карьеру, одним из самых главных советов самому себе был бы следующий: используй инструменты! Как сейчас помню, писал курсовую работу, задача которой была получить изображение с камеры, обработать его набором алгоритмов, записать некоторые данные в базу и отобразить готовую картинку на экран. И это все в режиме реального времени. Сложнее всего было отлаживать такую программу: нужно было одновременно следить за ошибками в работе с камерой, правильностью алгоритма, обращениями к базе данных и, конечно же, за работой с UI-фреймворком (кто имел дело с WPF-стилизацией, тот меня поймет). Со временем, набив несколько шишек и поучаствовав в создании ряда веб-проектов, я выработал для себя набор принципов, которые могут помочь справиться с этой сложностью.

Как и любой уважающий себя джун, я брался за решение задачи целиком: для того чтобы сверстать страницу, мне приходилось создавать веб-приложение в Visual Studio из темплейта, среди списка существующих файлов находить нужную страницу и писать HTML/CSS наугад, так как результат можно увидеть в браузере только после нажатия F5. Если нужно было отправить запрос на сервер, я добавлял кнопку на страницу, вешал на нее обработчик, добавлял логику построения HTTP-запроса, нажимал F5 и только после клика кнопкой мог посмотреть, правильно ли я описал обработчик запроса на сервере. Visual Studio была моей точкой входа в приложение и точкой выхода. Часто я даже не понимал, что происходит при нажатии на F5, потому что целью было решить ту или иную задачу. Знакомо?

image1_to4FZdw.png


Разделяй и властвуй​

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

Эта стратегия уменьшения сложности задачи путем ее разделения на более простые подзадачи известна как «разделяй и властвуй». В этом случае есть два предположения, которые обычно верны:

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

Верстка и фронтенд​

Сейчас, если мне нужно написать UI, я не запускаю сервер. Вместо этого открываю онлайн-редактор (например, Codepen) и верстаю нужные мне компоненты. Если мне нужно редактировать уже существующую часть приложения, то Chrome позволяет редактировать HTML/CSS на лету, используя вкладку Elements в Chrome DevTools. После этого останется всего лишь скопировать финальную версию и вставить себе в приложение (это намного проще, чем перезапускать приложение после каждого малейшего изменения). Кроме этого, DevTools позволяет отлаживать JS (не алертами, а с помощью переходов), расставлять точки останова, отслеживать переменные и читать Call stack. Отдельные экстеншены дают возможность упростить работу с JS-фреймворками (Angular, React), отслеживать состояние приложения (Redux) и производительность.

Коммуникация между клиентом и сервером​

Если мне нужно отправить запрос, я уже не создаю кнопку Test на форме. Вместо этого есть несколько инструментов, которые позволяют описать HTTP-запросы во всех деталях: cURL, Postman, Fiddler, RESTClient. Последний мне нравится больше всего, так как это экстеншен к VS Code и он позволяет описывать все запросы в виде интерактивного текстового файла, которым легко управлять. Если мне нужно более внимательно анализировать сетевой трафик, то можно обратиться к Fiddler или Wireshark. Таким образом я могу сфокусироваться на разработке конкретного API-метода в какой-то момент времени, не обращая внимания на остальную часть приложения.

Разработка бизнес-логики​

Если говорить о бизнес-логике приложения, то в первую очередь в голову приходят юнит-тесты. Вместо того чтобы запускать все приложение целиком, юнит-тесты позволяют сфокусироваться на конкретной функции, которую можно вызвать с теми или иными аргументами. VS предоставляет удобный интерфейс, для того чтобы запускать и отлаживать тесты, а для их написания можно использовать один из следующих фреймворков: xUnit, NUnit, MSTest. Необязательно добиваться стопроцентного покрытия тестами, достаточно уже того, что вы сможете проверить правильную работу своего кода без запуска приложения целиком. Я специально ни слова не сказал о дебаге, потому что, мне кажется, это первое, с чем сталкиваются начинающие программисты. Но, кроме дебага, я советую также разобраться с дизассемблером и научиться читать чужой код (пакеты, библиотеки). Это даст вам более широкую картину того, что происходит за ширмой библиотечных вызовов.

Взаимодействие с базой данных​

Не стоит забывать и о данных. ORM всячески стараются скрыть от разработчика работу с SQL. Вы пишете модель, затем пару вызовов библиотечных функций и получаете необходимую выборку. Но чем сложнее система, тем сложнее выглядит эта модель и тем большее у нее число функций. Поэтому заранее вооружитесь инструментами для работы с базой данных: IDE, профилировщиком, анализатором структуры запросов, анализатором логов. Если вы работаете с MS SQL, то большинство инструментов идет из коробки (MS SQL Management Studio, SQL Server Profiler, Execution Plan Analyzer), для других баз данных вам придется гуглить каждый инструмент по ключевым словам.

image2_9TwJNSP.png


Очень важно, чтобы вы не просто разбили приложение на отдельные составляющие, а и в тех местах, где определили «швы», описали заглушки: мок-данные, скрипты с HTTP-запросами, SQL-запросы. Это может быть полезно по двум причинам: во-первых, чтобы всегда можно было проверить изолированный компонент, а во-вторых, чтобы при объединении всех частей у вас перед глазами был контракт, которому необходимо следовать.

Перед тем как подвести итог, хотел бы дать пример разработки конкретной фичи (логина пользователя), используя все то, что я перечислил выше:

  1. В первую очередь я фокусируюсь на UI. Как сказано выше, открываю CodePen и стараюсь нарисовать интерфейс компонента, который соответствует мокапам (два поля для ввода логина и пароля и кнопка Login).
  2. Когда UI готов, могу перенести весь код в компонент и создать все необходимые обработчики. На этом этапе заменяю все сервисы по работе с данными сервисами с объектами-заглушками, для того чтобы проверить функционирование кнопки без обращений к серверу.
  3. После того как все операции по работе с формой (клик на кнопку, валидация, сообщения об ошибке или переход на другую страницу приложения) правильно заработают с объектами-заглушками, могу переключиться на бэкенд. Сначала описываю эндпоинт, который принимает модель и возвращает код 200. Используя RESTClient, описываю HTTP-запрос в текстовом файле (адрес, заголовки и тело запроса) и проверяю, чтобы мой сервер отвечал правильно.
  4. Перед тем как приступить к бизнес-логике, посмотрю в базу данных и проверю, все ли запросы, которые связаны с авторизацией, можно выполнить на существующих данных. Так как обычно я использую ORM, этот шаг является всего лишь подстраховкой, потому что ORM сама построит все запросы, а мне нужно только правильно описать модель.
  5. Теперь я могу приступить к бизнес-логике. Не буду вдаваться в подробности реализации функционала авторизации, хочу лишь сказать, что на этом этапе правильность вашего алгоритма легче всего проверить с помощью юнит-тестов. Добившись того, чтобы моя функция авторизации работала правильно, я могу подключить ее к базе данных, вызвать посредством API-метода и проверить целую связку, используя все тот же текстовый файл с запросом.
  6. Когда связка «API + логика + база данных» работает, я могу заменить на клиенте сервисы с заглушками реальными запросами к серверу и, если все контракты были описаны правильно, автоматически получаю рабочий функционал. Стоит отметить, что до последнего шага я каждый раз фокусировался на маленьком участке программы и только в конце запустил все приложение целиком.
tips-for-junior-developers


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

Во-вторых, баги никуда не денутся, однако такой подход дает больше возможностей для контроля на каждом этапе. Если, например, вы видите, что ваш сервер возвращает не те данные (пользуясь вкладкой Network в браузере), можете переключиться на текстовый файл запросов и не использовать браузер до тех пор, пока сервер не будет работать правильно.

В-третьих, вы могли заметить, что в процессе разработки у меня появилось несколько дополнительных артефактов: mock-сервисы с заглушками, текстовый файл с HTTP-запросами, юнит-тесты и запросы к базе данных (которые тоже желательно сохранять в отдельные файлы). В дальнейшем все эти артефакты вам придется поддерживать. Конечно, вы всегда можете избавиться от дополнительных файлов, как только закончите разработку конкретной фичи, но я крайне не рекомендую этого делать. Гораздо лучше постоянно строить себе подобного рода «леса», для того чтобы в любой момент времени было на что опереться.

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

И все же, запомните главное :)

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

 
Сверху