Боремось з одвічною проблемою IT-продуктів — технічним боргом
Привіт, я — Артур, Associate Director в команді продуктової студії Railsware. У компанії я вже 10 років, і цей досвід переконав, що якість роботи та репутація команди — не просто красиві слова, а критично важливий аспект успіху в IT-індустрії. Фактично це означає наявність продуктового майндсету у всіх членів команди та бажання вдосконалювати свій крафт, що дозволяє нам створювати надійні робочі продукти за адекватний час та гроші.
Важливо розуміти, що навіть при найкращих намірах виникає і накопичується технічний борг (TБ чи tech debt). З цим стикається будь-яка IT-компанія. І нехай слово «технічний» не вводить в оману. По суті, це як і борг у реальному світі: ви можете взяти позику для швидкого старту, але в кінці треба його повернути, часто — з великими відсотками. Тож якщо не управляти технічним боргом, він може звести нанівець всі ваші зусилля щодо продукту чи навіть серйозно зашкодити здоровʼю компанії.
Ця стаття стане в пригоді широкому колу колег. Продактам та проджект-менеджерам, які хочуть зрозуміти, як управляти технічним боргом та як він впливає на розвиток продукту. Розробникам, які хочуть краще розуміти наслідки своїх технічних рішень. Студентам і початківцям в IT, які хочуть зрозуміти, що таке технічний борг і як з ним боротися. Сподіваюся, допоможу вам розібратися в цій складній темі, щоб ви могли створювати кращі продукти і досягати більшого успіху в своїй кар’єрі.
Як я розумію технічний борг
Коли я був просто інженером, технічний борг для мене був скоріше результатом недосконалих технологій, неправильних рішень, недостатніх знань чи процесів, або ж часто змінюваних бізнес-вимог. Коли моя роль в команді перейшла на управлінський щабель, я переоцінив багато речей і подивився на розробку вже з точки зору менеджменту, а саме — керування ресурсами. Тому зараз для мене очевидно, що технічний борг — це ще й вартість переробки програмного забезпечення, яке стало важко модифікувати або підтримувати.
Технічний борг виникає, коли девелопери йдуть на компромісні рішення задля пришвидшення розробки. Найчастіше це все, що ви збираєтесь пофіксити пізніше. Але це пізніше так ніколи й не настає. Проте не всі проблеми варто вважати технічним боргом.
Для себе я визначив, що технічний борг не зводиться до кількох FIX-ME, або TO-DO у кодовій базі. Це радше нюанси ніж борг, як і баги, або погано написаний код. Баги можуть виникати через ТБ, але вони не є основною проблемою. Так само і брудний код.
Технічним боргом полюбляють називати як борг коду, так і архітектури. Тому багато хто неправильно його розуміє і не вміє відстежувати. Я користуюсь двома ознаками виникнення та накопичення ТБ, які легко помітити:
- інженерам стало важко впроваджувати зміни в програмне забезпечення,
- код стає складнішим після внесення простих змін.
Ризики накопичення технічного боргу
Як і фінансовий борг, ТБ з часом тільки збільшується. Чим довше його ігнорувати, тим дорожче він вам коштуватиме. Наведу вам декілька прикладів негативних наслідків ТБ, що псують життя усім членам команди:
- Непередбачені витрати в майбутньому. Наприклад, якщо команда інженерів не в змозі регулярно оновлювати залежності, у певний момент їй доведеться витратити незапланований час на заміну застарілих бібліотек чи фреймворків.
- Погіршення якості продукту та його можливості масштабуватись.
- Ускладнений ріст команди.
- Неякісна документація, на яку вже не можна покладатись.
- Відсутність прогресу розробки через накопичення критичної маси ТБ, оскільки інженери вимушені витрачати весь час на переробку продукту.
- Швидке вигоряння спеціалістів, що змушені працювати над проблемами, яких можна було б уникнути.
Якщо борг не контролювати, він може серйозно вплинути на прибутки вашої команди (або прибутки клієнта, якщо ви надаєте послуги розробки, а зрештою — і на ваші).
Як краще слідкувати за ТБ
Коли Вейд Каннінгем вперше ввів термін технічний борг у
Архітектурний борг. Виникає, коли ми приймаємо неоптимальні рішення або недостатньо добре продумуємо архітектуру системи. Наприклад, ви створюєте вебзастосунок за допомогою платформи з готовими шматками коду (штибу WordPress). Пізніше, отримавши відгуки користувачів, ви розумієте, що продукт потребує значно більше налаштувань, ніж може запропонувати платформа.
Борг коду. Накопичується, якщо написаний код важко розуміти, оновлювати, або підтримувати. Код може бути надскладним, непослідовним, або містити помилки, що призводять до багів та інших проблем.
Інфраструктурний борг. Може накопичуватися, якщо інфраструктуру (сервери, бази даних тощо) не підтримувати належним чином та не оновлювати. Як результат отримаємо критичні проблеми зі швидкодією, такі як затримки в роботі чи повільне завантаження ключових функцій продукту.
Борг документації. Виникає, коли розробники не вміють правильно документувати свій код. Відсутні, неповні, або застарілі пояснення тільки спантеличать колег і нових членів команди. Якщо продукт великий, борг документації ускладнить інженерам розуміння, як відбуваються певні процеси, як працюють фічі і як частини кодової бази поєднані між собою.
Борг даних. Виникає, якщо не приділяти достатньо уваги управлінню даними. Нездатність правильно організовувати інформаційні масиви, дублювання даних або їхня повна відсутність погіршує досвід користувачів та змушує їх шукати альтернативу вашому продукту.
Борг безпеки. Накопичується, якщо не вживати належних заходів під час розробки ПЗ. Наприклад, якщо команда відкладає усунення відомої вразливості системи, яка серйозно збільшує ймовірність атаки шляхом SQL-ін’єкції. Некерований борг безпеки може призвести до масивних витоків даних та інших проблем.
Як виникає технічний борг
Перш ніж я розкажу про те, як наша команда бореться з ТБ, я хотів би навести основні причини його виникнення, щоб вам було зрозуміліше з чим саме варто боротись.
Причини, пов’язані з управлінням
Жорсткі дедлайни. Повсюдна причина технічної заборгованості. Коли менеджмент виділяє мало часу на розробку, інженери змушені обирати компромісні рішення. Наприклад, вони можуть створити функціональну систему, що не може масштабуватись. Незалежно від того, чи є ці компромісні рішення обдуманими, чи ні, команда має бути готовою до їхніх наслідків. Тобто, в майбутньому запланувати ресурси на рефакторинг.
Недостатня комунікація. Якщо розробники не знають цілей, пріоритетів і часових рамок проєкту, вони не зможуть прийняти правильні рішення. Критичні системні збої неминучі, якщо команда недостатньо обговорила архітектуру продукту чи дизайн інфраструктури.
Відсутність планування. Неспроможність визначити візію продукту та поставити досяжні цілі призведе до виникнення та зростання технічного боргу. Коли команді бракує спрямування, вона, швидше за все, обере неправильний підхід, або працюватиме над завданнями, які не просувають проєкт вперед.
Часта зміна стратегії або вимог. Різкі зміни або доповнення до специфікації проєкту також можуть призвести до накопичення технічного боргу.
Дефіцит ресурсів. Неукомплектовані команди розробників зазвичай не мають достатньо часу для перевірки всіх edge cases. Щоб встигнути вчасно, вони змушені ігнорувати найкращі практики, як-от перевірка пул реквестів, написання автотестів, ведення детальної документації тощо.
Причини, пов’язані з командою
Брак експертизи. Недосвідчені інженери часто приймають неправильні рішення, які призводять до технічних боргів. Наприклад, їхній код може містити багато дуплікацій, що ускладнює пошук і виправлення потенційних багів. Вони з меншою ймовірністю будуть дотримуватись правил неймінгу, використовувати належні шаблони та структури мови програмування або правильно форматувати свій код. А це ускладнить іншим інженерам його розуміння та підтримку в майбутньому.
Байдужість. Коли розробники не беруть на себе відповідальність за свою роботу або недостатньо дбають про її якість, страждає в першу чергу продукт. Недбалість може призвести до серйозних проблем в коді, які колись доведеться вирішити.
Оверінжиніринг. Прагнення до досконалості також може мати зворотний результат. Складність заради складності часто створює непотрібні труднощі. Наприклад, якщо команда занадто рано перейде від монолітної архітектури до мікросервісів, це ускладнить можливість внесення змін у наступних ітераціях.
Помилки. Звичайно помилки роблять усі, навіть досвідчені розробники. Іноді, попри попередні дослідження та планування, правильне рішення стає очевидним лише після того, як помилки з’явились. Це одна з причин, чому технічний борг неминучий.
Навмисний і ненавмисний технічний борг
Навмисний технічний борг виникає, коли команда усвідомлено приймає компромісні рішення задля досягнення короткострокової мети. Частіше це трапляється на початку розробки, коли швидкість виходу продукту на ринок — пріоритет (створення прототипу, MVP тощо). Але подібні ситуації також трапляються, коли є жорсткі дедлайни, а команда мусить випустити оновлення в строк.
Ненавмисний технічний борг виникає в результаті неправильного вибору дизайну, відсутності уваги до деталей, недостатнього розуміння продукту. Іншими словами, це випадковість.
Як працювати з технічним боргом
Ми з командою переконалися на практиці, що проблему краще попередити, ніж вирішувати. Ось декілька практик, які ми використовуємо в компанії, щоб запобігти, відстежити та розв’язати проблему технічної заборгованості.
Детальне планування
Без готової стратегії продукту і плану, як її реалізувати, команда інженерів не може приймати правильні рішення. Ось чому так важливо мати роадмеп — дорожню карту продукту.
Дорожня карта — це більше ніж просто перелік завдань. Ми вважаємо її «живим» документом, який відображає усі важливі елементи стратегії продукту. Вона містить чітко пріоритезовані фічі, щоб члени команди від початку знали, на чому зосередити зусилля. З першого погляду інженери бачать пріоритети проєкту і розуміють, як їхній код буде впливати на продукт в цілому.
Водночас саме беклог допомагає команді своєчасно відстежувати технічні борги. Знаю, часом просто хочеться вдати, що проблеми не існує. Але якщо ви будете чітко відстежувати виникнення проблем, вирішувати їх буде набагато легше (і дешевше).
Отже, інженери повинні створювати тікети в беклозі кожного разу, коли помічають проблему. І коли команда матиме вільні ресурси, вона зможе пріоритезувати проблему та вирішити її малими зусиллями.
Фокус на важливому
Не всі проблеми є однаково важливими. Часто немає сенсу рефакторити фічу, яка відіграє незначну роль в користуванні продуктом. Краще, зверніть увагу на код, який насправді має значення. У кожній ітерації працюйте над покращенням ключової архітектури продукту та елементами інфраструктури. Поступово підвищуйте загальну гнучкість продукту і не витрачайте час на постійне удосконалення «достатньо хорошого» коду.
Ми прийшли до того, що рефакторимо код лише тоді, коли в цьому є нагальна й вагома потреба. Таким чином ми не витрачаємо ресурси на фікс несуттєвих речей. Разом з тим, кожен із нас залюбки працює над маленькими покращеннями, коли є така можливість. У нас навіть діє «правило бойскаутів»: залишати код кращим, ніж знайшли.
Увага до інженерів
Менеджмент команди має завжди активно прислухатися до інженерів і їхнього бачення проблеми. На мою думку, інженери краще за всіх можуть передбачити ТБ та запропонувати способи, як його уникнути. Варто скористатись їхнім досвідом та створити стійкіший та ефективніший продукт.
Досить дієвою також є культура відкритого фідбеку, де всіх членів команди заохочують висловлювати свої думки і занепокоєння.
Спрощена ієрархія в команді
Чіткий розподіл на посади та жорстка ієрархія часто спричиняють непотрібні ускладнення в agile командах. Однак я вважаю, що чим більш автономними є інженери, тим кращі продукти вони створюють. Наша команда тяжіє до холакратичної структури організації, що й допомагає нам розвивати культуру відповідальності на всіх рівнях.
Як це не дивно звучить, але в Railsware немає менеджерів, що призначають ролі й розподіляють задачі. Ми самостійно організуємося в команди і гільдії, щоб тісно співпрацювати та досягати спільної мети.
Поясню на прикладі команди нашого SaaS-продукту Mailtrap — у ній окремі гільдії створюються під час кожного спринту. Ось деякі з них:
- Гільдія фронтенду. Інженери працюють над новими фічами, підтримують чистоту коду на фронтенді та впроваджують нові підходи за потреби.
- Гільдія підтримки. Розробники працюють над удосконаленням тих частин системи, у яких були виявлені помилки.
- Гільдія OSS працює над тими аспектами продукту, де використовуються опенсорсні інструменти (геми, SDK).
- Гільдія безпеки працює над посиленням захисту даних шляхом покращення процесів доступу до них та управління доступом до ресурсів проєкту.
У контексті запобігання ТБ «гільдійний» підхід має кілька ключових переваг. По-перше, команда отримує виділений час і ресурси для вдосконалення системи та усунення проблемних місць в коді. По-друге, члени команди можуть працювати над різними частинами проєкту протягом кількох місяців, що дозволяє їм глибше розуміти вимоги проєкту та активніше долучатись до прийняття рішень щодо його розвитку.
Виділення ресурсів на парне програмування
Робота в парах допомагає нам ефективніше розв’язувати проблеми та створювати кращі, надійніші рішення. Тому ми дуже часто практикуємо її для різних цілей. Такі сесії зазвичай тривають
Коли справа доходить до запобігання технічним боргам, основні переваги парного програмування — це:
- Код кращої якості. З додатковою парою очей баги легше помітити й відразу пофіксити. Так в них не буде шансів перетворитися на технічний борг.
- Можливість побачити загальну картину. Коли інженери працюють у парах, вони вже розглядають не одну, а дві точки зору, що допомагає формувати спільне розуміння продукту.
- Обмін знаннями. Члени команди мають більше можливостей для спілкування. Це допомагає їм приймати кращі рішення та підтримувати сталий ріст продукту.
Регулярна перевірка пул-реквестів
Регулярні та ретельні перевірки пул-реквестів — основний захід, щоб запобігати накопиченню технічного боргу. Ця практика дає змогу командам на ранній стадії виявляти несправний код та інші проблемні аспекти.
Отже, задля консистентної якості таких перевірок, варто розробити та дотримуватись єдиного протоколу перевірки всіх пул-реквестів. Якщо процес поставити на рейки, вам буде легше виявляти потенційні проблеми, обговорювати та швидко їх фіксити.
Ось кілька порад, як це краще зробити:
- Перед відправкою пул-реквеста на перевірку, автор має спробувати дистанціюватися від свого коду та поглянути на нього об’єктивно в контексті продукту. Таким чином він зможе виправити деякі явні відхилення та зменшити частину робочого навантаження на перевіряючого.
- Для великих і складних пул-реквестів автори повинні додавати to-do списки до їхнього опису.
- Інженери-ревʼювери мають бути проактивними та переглядати пул-реквести принаймні раз на день.
- Під час перевірки, ревʼюверам варто переконатися, що їхні коментарі чіткі, практичні та коректні. На сайті Conventional Comments можна знайти багато гарних прикладів.
- Якщо пул-реквест занадто великий або незрозумілий, рев’ювер має зв’язатись з автором та разом перевірити код.
- Автоматизуйте перевірку. В нашій RoR-команді ми часто використовуємо Rubocop для належного форматування коду та виявлення потенційних проблем.
- Також, користуємось Simplecov для перевірки покриття коду та Brakeman для пошуку будь-яких проблем безпеки.
- Команда має прагнути закрити пул-реквест протягом
2-3 днів, інакше накопичиться багато роботи і буде важче приділити кожній задачі належну увагу. - Коли рев’ювер бачить, що щось можна покращити, але це напряму не стосується цілей пул-реквеста, він все одно має його заапрувити і залишити свій коментар щодо покращення. Вказуйте на помилки, пропонуйте кращі назви змінних, але завжди пам’ятайте про пріоритети проєкту.
Наостанок
Усі ми хочемо, щоб технічного боргу не існувало. Але це нереально. Тому, щоб не дати ТБ завдати серйозної шкоди продуктові, важливо чітко розуміти, що це таке та як він накопичується. Важливо переконатися, що усі інженери залучені до процесу прийняття рішення та мають автономію, щоб брати на себе відповідальність за технічний борг і бути більш активними в керуванні ним.
Проведення регулярних сесій код рев’ю допоможе команді тримати технічний борг під контролем та правильно визначати пріоритетність проблем. А парне програмування сприятиме виявленню проблеми на ранній стадії та допоможе переконатися, що код відповідає необхідним стандартам.
Що допомагає вам в боротьбі з технічним боргом? Діліться у коментарях!
16 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів