Як починаючому розробнику уникнути нестримної налагодження, червоних очей і зіпсованого настрою

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

Використовуй готові інструменти

Якби я міг повернутися в той час, коли тільки починав свою кар'єру, одним з найголовніших рад самому собі був би наступний: використовуй інструменти! Як зараз пам'ятаю, писав курсову роботу, завдання якої була отримати зображення з камери, обробити його набором алгоритмів, записати деякі дані в базу і відобразити готову картинку на екран. І це все в режимі реального часу. Складніше всього було налагоджувати таку програму: потрібно було одночасно слідкувати за помилками в роботі з камерою, правильністю алгоритму, зверненнями до бази даних і, звичайно ж, за роботою з UI-фреймворком (хто мав справу з WPF-стилізацією, той мене зрозуміє). З часом, набивши кілька шишок і взявши участь у створенні низки веб-проектів, я виробив для себе набір принципів, які можуть допомогти впоратися з цією складністю.

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

Розділяй і володарюй

Будучи коучем 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), для інших баз даних вам доведеться гуглити кожен інструмент за ключовими словами.

Дуже важливо, щоб ви не просто розбили додаток на окремі складові, а й в тих місцях, де визначили «шви», описали заглушки: мок-дані, скрипти з HTTP-запитами SQL-запити. Це може бути корисно з двох причин: по-перше, щоб завжди можна було перевірити окремий компонент, а по-друге, щоб при об'єднанні всіх частин у вас перед очима був контракт, яким необхідно слідувати.

Перед тим, як підвести підсумок, хотів би дати приклад розробки конкретної фічі (логіну користувача), використовуючи все те, що я перерахував вище:

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

Звичайно, такий підхід не ідеальний і має свої вади. По-перше, тут дуже важлива дисципліна. Завжди хочеться взятися за все і відразу. Важливо навчитися ділити велику задачу на кілька складових і фокусуватися на кожній з них окремо, відкидаючи все інше на потім.

По-друге, баги нікуди не подінуться, однак такий підхід дає більше можливостей для контролю на кожному етапі. Якщо, наприклад, ви бачите, що ваш сервер не повертає (користуючись вкладкою Network в браузері), можете переключитися на текстовий файл запитів і не використовувати браузер до тих пір, поки сервер не буде працювати правильно.

По-третє, ви могли помітити, що в процесі розробки у мене з'явилося кілька додаткових артефактів: mock-сервіси з заглушками, текстовий файл з HTTP-запитами, юніт-тести і запити до бази даних (які теж бажано зберігати в окремі файли). Надалі всі ці артефакти вам доведеться підтримувати. Звичайно, ви завжди можете позбутися від додаткових файлів, як тільки закінчите розробку конкретної фічі, але я вкрай не рекомендую цього робити. Набагато краще постійно будувати собі подібного роду «лісу», для того щоб в будь-який момент часу було на що спертися.

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

І все ж, запам'ятайте головне :)

Коли я починав свій шлях розробника, то не зміг знайти такої статті, яка підштовхнула мене в правильному напрямку. Це коштувало мені незліченної кількості годин нестримної налагодження, червоних очей і зіпсованого настрою. Спостерігаючи за нинішніми студентами, я часто бачу, як вони наступають на ті ж граблі: витрачають багато часу на вже вирішені проблеми, замість того, щоб сконцентрувати всі зусилля на предметній області, а другорядні завдання делегувати інструментів. І навіть якщо описаний вище підхід до вашого нагоди непридатний, а написання додаткового коду в тягар, запам'ятайте головне: використовуйте інструменти!

Опубліковано: 17/04/20 @ 10:00
Розділ Різне

Рекомендуємо:

"Мене скоротили". Історії IT-спеціалістів, які залишилися без роботи через коронакризу
16-річний програміст із Черкащини – про ті, як 11-класником влаштувався на роботу зі зарплатнею майже $1000
DevOps дайджест #31: COVID-19, Kubernetes 1.18 і NTP в Facebook
Як працювати віддалено: перехід з роботи в офісі на удаленку
Problem Solving: 7 факторів для визначення і правильного аналізу проблеми