Бізнес

Виправити, рефакторити чи переписати успадкований застосунок

ПР

Павло Рубановський

· 6 хв читання

Виправити, рефакторити чи переписати успадкований застосунок

Лишайте те, що працює, виправляйте локальні баги, рефакторте те, що гальмує кожну зміну, і переписуйте лише те, що дешевше замінити, ніж полагодити, — для кожної частини окремо, після читання коду, а не для всього застосунку одразу. Більшості успадкованих застосунків потрібно кілька таких рішень у різних місцях. Переписати все — виняток, а не відправна точка.

Чотири висновки поруч

ВисновокКоли підходитьРизик
Лишити — не чіпати частинуВона працює, і зміни в ній лишаються локальнимиНемає — нічого не змінюється
Виправити — змінити зламане, структуру лишитиАрхітектура здорова, проблеми локальніНизький
Рефакторити — перебудувати код, користувачі змін не бачатьКожна зміна повільна або ламає щось іншеСередній — спершу напишіть тести навколо цієї зони
Переписати — замінити частину новим кодомЛагодити дорожче, ніж замінитиВисокий — усе, що «знав» старий код, доведеться відкривати заново

Ключове слово — *частина*: це рішення про частини застосунку, а не ярлики для нього цілого. Платіжний сценарій (флоу) може потребувати переписування, а онбординг поруч — нічого.

Ознаки, що частину варто лишити й виправити

  • Вона робить те, що потрібно користувачам, а баги конкретні: збій на одному екрані, хибний розрахунок, проблема з версткою на одному пристрої.
  • Код достатньо читабельний, щоб новий розробник знайшов, куди вносити зміну.
  • Зміни в ній лишаються в ній — виправлення однієї речі не ламає дві інші.
  • Вона збирається сучасними інструментами збірки (тулчейном) або збереться після звичайних оновлень.

Сюди потрапляє більша частина типового успадкованого застосунку. Старе не означає погане, а незнайоме — неправильне.

Ознаки, що потрібен рефакторинг

  • Кожна дрібна зміна займає дні, бо логіка розкидана по екранах, віджетах і сервісах.
  • Одне бізнес-правило реалізоване в трьох місцях, і вони суперечать одне одному.
  • Станом — даними, які екран показує й змінює, — керують кількома різними способами в одному застосунку, нашарованими один на одного.
  • Ніхто не наважується торкатися файлу, бо останній, хто торкнувся, зламав оплату.

Рефакторинг зберігає поведінку незмінною, а наступну зміну робить дешевою. Найбезпечніше робити його малими кроками, випускаючи кожен окремо, і писати тести навколо зони *до* перебудови — щоб довести, що для користувачів нічого не змінилося.

Ознаки, що переписати дешевше

Переписування частини виправдане, коли справджується одне чи кілька з цього:

1. Її не можна зробити безпечною. Логіка переплетена з інтерфейсом, тестів немає, а частина працює з грошима, автентифікацією чи персональними даними. 2. Фундаменту більше немає. Вона залежить від покинутого фреймворку чи пакета, який блокує оновлення всього іншого. 3. Продукт став іншим. Частину будували під сценарій, якого вже немає, і тепер її підганяють під новий. 4. Вона невелика. Замінити кілька екранів дешевше, ніж розбиратися в їхній історії.

Навіть тоді переписування має обмежуватися цією частиною, мати власну ціну й виходити окремим релізом.

Чому «переписати все» — хибна перша відповідь

Нова команда, яка пропонує повне переписування, ще не прочитавши код, описує свої вподобання, а не ваш застосунок. Ризики добре відомі — есей Джоела Спольскі Things You Should Never Do досі лишається класичним описом — і для мобільних застосунків вони так само актуальні:

  • Старий код зберігає знання. Кожна дивна на вигляд умова — зазвичай баг, який хтось виправив для реального користувача на реальному пристрої.
  • Відтворити всі старі функції (паритет функцій) довше, ніж будь-хто пам’ятає. Крайні випадки, налаштування, міграції збережених даних, пуш-сценарії, діплінки.
  • Ви платите двічі. Старий застосунок однаково потребує виправлень, поки будується новий.
  • Довго нічого не виходить. Користувачі й інвестори не бачать прогресу, доки нова версія не готова повністю.

DriveCode розробляє застосунки для iOS та Android, Flutter-first. Коли ми підхоплюємо застосунок, за замовчуванням лишаємо те, що працює, і замінюємо лише те, що за результатами огляду дешевше замінити.

Рішення для кожної частини

Ці питання до кожної зони застосунку зазвичай усе вирішують:

ПитанняЯкщо такЯкщо ні
Чи робить вона те, що потрібно користувачам сьогодні?Лишити або виправитиПереписати може бути дешевше
Чи можна змінити її, не зламавши щось інше?ВиправитиСпершу рефакторинг
Чи є тести, або чи можна їх додати до того, як чіпати?Безпечний рефакторингДодати тести або розглядати як кандидата на переписування
Чи збирається вона сучасним тулчейном після звичайних оновлень?ВиправитиПеревірити, чи можна замінити її залежності
Чи займе заміна менше часу, ніж розібратися в ній?ПереписатиЛишити

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

Якщо застосунок нативний: перехід на Flutter — інше рішення

Перенесення нативного застосунку для iOS та Android на Flutter — це за визначенням переписування, але заплановане й зі своїми причинами: одна кодова база замість двох, одна команда замість двох. Це не вирок якості нативного коду.

Ми робимо це за принципом «спершу ядро»: Flutter-ядро виходить як компактний MVP, поки нативні застосунки й далі отримують оновлення; решта приходить у регулярних оновленнях, починаючи з найпотрібніших. Детальніше — у статтях як перенести нативний застосунок на Flutter без заморозки фіч і скільки коштує такий перехід, а також на сторінці міграції.

Не зупиняйте релізи, поки вирішуєте

Хоч яким буде висновок, релізи не мають зупинятися. На практиці перший модуль роботи часто найменш ефектний: повернути застосунок у стан, коли звичайне оновлення можна зібрати й опублікувати з ваших акаунтів. Після цього виправлення й рефакторинг виходять звичайними оновленнями, а переписана частина — тоді, коли готова вона, а не весь застосунок.

Що часто питають

Чи буває повне переписування правильним рішенням? Так — коли застосунок невеликий, коли майже кожна частина не проходить питань вище або коли продукт змінився настільки, що від старого мало що лишилось. Але це має бути висновок із прочитаного коду, а не стартова пропозиція.

Як зрозуміти, що команда не просто продає мені переписування? Попросіть висновок для кожної частини з причинами. Команда, яка читала ваш код, назве конкретні файли й сценарії; та, що не читала, говоритиме про «технічний борг» загалом.

Чи можна рефакторити й додавати функції водночас? Так — у різних частинах застосунку або рефакторячи зону безпосередньо перед тим, як додати в неї функцію. Уникати варто довгого рефакторингу без релізів.

Скільки коштує кожен варіант? Залежить від розміру кожної частини, тому ми встановлюємо фіксовану ціну за кожен модуль після огляду вашого застосунку. Проєкти — від $10K.

Розпочати проєкт

Сподобалося?
Давайте будувати разом.

Відповідь протягом 24 годин · NDA готові · Повна власність на код