Як модернізувати легасі-код. Технічні аспекти рефакторингу

Привіт! Мене звати Дмитро Ханджанов, я фронтенд-розробник із майже 10-річним досвідом розробки проєктів у різних доменах. Познайомлю з деякими з них, адже саме за досвідом можна оцінити навички розробника:

  • Health-care проєкт, де на перше місце ставилася автономність. Ми мали працювати офлайн і передавати дані на сервер у короткі проміжки часу, коли з’являвся зв’язок.
  • Трекінгові системи, які відстежували переміщення користувача всередині приміщень і організовували дані для аналітики. Не варто й казати, з якими обсягами інформації доводилося працювати :)
  • Платформа для кіберспортсменів і гравців у CS2, яка налічує понад 4 мільйони користувачів зі 168 країн світу, де на перше місце ставиться інтерактивність, реактивність і відмовостійкість системи. Мій поточний проєкт.

Тепер, коли я вже представився і з підозрілої особистості став трохи знайомою, гайда без зайвих слів перейдемо до теми нашої розмови, а саме до рефакторингу проєктів.

Як сприймати статтю

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

Стаття буде розділена на дві частини: технічну та організаційну. У першій, технічній частині, ми розглянемо питання прийняття рішень і основні підходи, які можуть цьому сприяти. А також торкнемося питання складання технічної документації. В другій, організаційній частині, обговоримо варіанти представлення ідеї менеджменту, а також окреслимо супутній обсяг робіт.

Що таке легасі-код. Як утворюється, яким буває

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

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

Для мене легасі-код поділяється на два види:

  • Добре написаний код на застарілих версіях мови/фреймворку. Такий код потрібно не стільки «рефакторити» у звичному розумінні цього слова, скільки переписати під нові стандарти, залишивши концепцію незмінною.
  • Розрослий MVP. Напевно, саме цей або подібний варіант першим спадає на думку при згадці легасі-коду. Тобто проєкт, який розростався з часом, із застосуванням компромісних рішень і приділенням недостатньої кількості часу на рефакторинг.

Саме такий кейс з другого пункту я і пропоную розібрати. Ми будемо не просто розбирати «погані запахи» коду, підбираючи під них рішення, а подивимося на картину ширше. Оцінимо стан проєкту загалом і розв’яжемо його проблеми на фундаментальному рівні.

Абстрактний проєкт для прикладу

Уявімо найбільш поширений з мого досвіду сценарій. Перед командою поставили завдання написати відносно невеликий додаток (MVP) для перевірки ідеї. Було прийнято рішення використовувати один із фреймворків (нехай це буде React), додати туди Redux для зручності та слідувати канонам фреймворку в розробці застосунку.

Минув час, MVP вистрілив, однак переписувати його під нові фічі замовник відмовився. Вирішили розвивати те, що вже працює. Так потроху з’явився якийсь кастомний middleware-прошарок між Redux і React-компонентами, куди перейшла частина логіки.

Ще частина загубилася десь у нескінченних helper’ах, utils’ах, handler’ах тощо.

У цей час змінювалися люди, хтось йшов, хтось приходив йому на заміну, і ось через декілька років команда утвердилася в думці, що немає нікого, хто б всеосяжно розумів, як проєкт функціонує. Функції з helper’ів і utils’ів у хаотичному порядку переплітаються з Redux’ом і middleware, і ніхто не хоче в них лізти, щоб нічого не зламати. А новий функціонал теж намагаються писати так, «аби нічого не зламати».

Тут знаходимось ми й починаємо його рефакторити.

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

Розуміння проблем або розробка вимог

З чого варто почати? Зрозуміти, чи заважає легасі-код продукту розвиватися. І якщо заважає, то як саме, і що тоді ми хочемо отримати після рефакторингу.

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

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

Для нашого абстрактного прикладу будуть актуальними проблеми з багатьма, якщо не з усіма, якостями архітектури. Можемо виділити наступні проблеми:

  1. Testability (тестованість). Погано спроєктована система неминуче призводить до дублювання коду та нехтування чистими функціями, що робить тестування якщо не неможливим, то вкрай складним завданням.
  2. Maintainability (підтримуваність). Через високу зв’язаність коду стають дуже ймовірними помилки на кшталт «тут полагодив, а там зламав», на виявлення та виправлення яких витрачається багато часу.
  3. Flexibility (гнучкість). Точки розширення функціональності проєкту важко виділити, через що для впровадження нової функціональності доводиться частково переписувати стару. Що в умовах відсутності тестів призводить до великої кількості багів.

Серед інших проблем, які також варто зауважити — відсутність структури проєкту, документації, knowledge holder’а. Це впливає на якість прийнятих рішень і залучення в проєкт нових розробників.

А також зростаюча з часом складність. На ілюстрації показано, як буде зростати складність проєкту залежно від обраного архітектурного патерна. Але можна помітити, що вона зростатиме в будь-якому випадку. Рано чи пізно впровадження нової функції або виправлення бага стане настільки непередбачуваним і дорогим, що проєкт перестануть підтримувати зовсім.

Розробка рішень

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

Наприклад, ви ж не будете переписувати проєкт з React на Angular тільки тому, що він краще підходить проєкту? Це вимагатиме повної заміни команди, інакше процес переписування буде ідеальною ілюстрацією фрази «через терни до зірок».

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

Роздiлення на шари

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

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

Крім того, завжди легше тримати в голові окремий модуль або шар, розуміючи його призначення та відповідальність, ніж оперувати відразу всім проєктом. Іншими словами, розділення на шари зменшує зв’язаність проєкту, що позитивно позначиться на Testability та Flexibility, з якими у нас, як ми пам’ятаємо, є проблеми.

Звичайно ж, є ряд підходів, які описують можливі варіанти розшарування архітектури та взаємодії між шарами. Для нашого «абстрактного проєкту» ми зупинимося на популярному Clean Architecture, але можна розглянути всі варіанти.

Clean Architecture. Описує розділення на шари таким чином, коли залежності рухаються лише ззовні всередину. Тобто умовний вебінтерфейс може мати доступ тільки до наступного умовного шару «controllers» або «middleware», а ті, своєю чергою, не можуть напряму керувати вебінтерфейсом.

Vertical Slice Architecture. Наступний еволюційний крок Clean Architecture, суть якого в реорганізації коду проєкту таким чином, щоб «шари» описували структуру кожної окремої функції як модуля.

Onion Architecture. Дуже схожа за своєю концепцією з Clean Architecture, але більш гнучка. Дає змогу різним частинам шарів спілкуватися між собою за допомогою обробників команд, подій тощо.

Ймовірно, наведені вище патерни далеко не всі, що описують способи розшарування проєкту. Але основні, з яких я б рекомендував почати знайомство.

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

Патерни та підходи, на які варто звернути увагу

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

Архітектурні патерни

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

Звісно, докладно розглядати всі патерни ми не будемо, але навести перелік таких шаблонних рішень, безумовно, необхідно:

MVC (Model-View-Controller). Мабуть, один з найбільш поширених патернів. Його суть полягає у створенні контролерів, які приймають команди від клієнта, створюють моделі. Які, своєю чергою, оновлюють уявлення (view).

MVP (Model-View-Provider). Дуже схожий з MVC патерн, відмінність якого полягає в тому, що модель не оновлює уявлення, а провайдер сам організовує дані та оновлює модель.

BLoC (Business Logic Component). Архітектурний патерн, що використовується для управління станом в застосунках, особливо популярних у Flutter. Він відокремлює бізнес-логіку від уявлення, організовуючи дані та події. Події передаються в блок, який обробляє їх і оновлює стан, передаючи його назад до уявлення.

VIPER. Архітектура, що має популярність у Swift. Містить перелік елементів з чітко розділеними зонами відповідальності та способом взаємодії між ними.

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

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

Модульність

Імплементуючи модульний моноліт, я не міг не помітити, що він на відмінно справляється з типовими проблемами фронтенд-розробки. Виділення модуля як окремого набору керуючих елементів у рамках домену дозволить:

1. Розділити розробників на команди.

2. Знизити зв’язаність проєкту (якщо забезпечити невзаємодію модулів).

3. Просто роздробити проєкт для кращого його розуміння.

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

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

Enterprise-патерни

Окремого згадування заслуговує ця категорія патернів. Частково вони вже були згадані вище, проте все-таки дуже багато залишилося за рамками цієї статті. Дані патерни описують рішення для типових проблем при побудові архітектури, організації потоків даних тощо.

Вони можуть описувати як структуру всього застосунку (MVC, MVVM тощо), так і окремих шарів (Data Mapper, Repository) і навіть окремих класів, призначених для спілкування між цими шарами (DTO, Query Object). Тому якщо виникають сумніви щодо якогось рішення в архітектурі — його, ймовірно, можна знайти в одному з цих патернів.

На відміну від GoF або GRASP, немає визначеного списку enterprise-патернів. Однак є безліч джерел, які надають такі списки в рамках певного контексту. Скажімо, патерни організації бізнес-логіки або зберігання даних. Просто обирайте свою область і майже напевно знайдете рішення своєї, типової проблеми.

Створення технічного дизайну

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

Ознаками хорошого технічного дизайну будуть логічність, структурованість і вичерпність. Технічний дизайн повинен пояснювати, як і чому ми будемо реструктурувати проєкт. Кожен розробник, прочитавши його, повинен приблизно уявляти, що потрібно зробити.

Є ряд форматів і стандартів, яких дотримуються архітектори для опису своїх рішень. Хочу зупинитись на двох з них:

C4. Формат, який дозволяє описати архітектуру проєкту для різних рівнів і завдань. Структура документа є тривимірною і розділяється від більш абстрактних ідей і тем до деталей окремих класів і їхніх зв’язків, що дає змогу «провалюватися» в деталі за потреби. Наприклад, архітектору буде цікавіше дивитися на архітектурне рішення загалом, тоді як виконавцю — подивитися на передбачувану реалізацію конкретного модуля.

ARC42. Це шаблон, який дозволяє створити зручний для читання технічний документ з мінімумом води. Кожен пункт плану в цьому шаблоні строго регламентований і описаний. Це дає розробнику певний чек-лист, щоб нічого не упустити, і водночас ставить рамки, щоб той не «лив воду», вправляючись у красномовності.

Складений технічний дизайн за описаними вище шаблонами легко може бути використаний як документація по проєкту. Як мінімум частково.

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

А саме:

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

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

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

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

Технічне рішення для нашого проєкту

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

Отже, для початку у нас є заявлені проблеми з Maintainability і Flexibility проєкту. Це означає, що насамперед потрібно розв’язати проблему: де зберігати код і як організувати його взаємодію.

Для цього пропоную використовувати вже згадані вище модулі. У них можна буде поступово переносити функції та класи з хелперів і утиліт. Розділяти ці модулі слід на домени, які є в застосунку.

Оскільки це React-додаток, нам не обійтися без Redux. Це де-факто вже стандарт в індустрії, навколо якого умільці налагодили цілий зоопарк технологій, за що я їм особисто не скажу «красно дякую».

Залишилася лише одна нерозв’язана проблема з заявлених — Testability. Для того, щоб досягти гарної тестованості коду, ми повинні забезпечити можливість тестувати не окремі функції, а бізнес-правила. У нас вже є модулі, в які ми будемо виносити код, що обробляє дані у своєму домені, проте можемо для кожного з них зробити один або кілька Facade, за якими приховаємо складність модуля. Та опишемо бізнес-правила обробки даних, які чудово покриються тестами.

Використання ж цих модулів пропоную винести в middleware-прошарок на кшталт Saga або Redux-Effects, щоб повністю позбавити компоненти застосунку необхідності готувати параметри або займатися ще чимось, крім рендерингу елементів.

У результаті ми отримаємо приблизно таку схему поділу шарів і їхньої комунікації: компоненти мають доступ лише до middleware і підписуються на зміни стора, водночас лише middleware має право і можливість викликати модулі, що містять бізнес-логіку.

Звичайно, багато ще потрібно вирішити, але це вже основа, з якої можна починати. Далі потрібно розв’язувати проблеми побудови транспортного шару для API та ізолювання коду за допомогою інверсії залежностей. Але це вже незначні деталі для нашого прикладу.

Висновки

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

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

👍ПодобаєтьсяСподобалось8
До обраногоВ обраному6
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Існує 12 атрибутів якості архітектури проєкту.

1) Їх не 12. Єдиної класифікації не існує. Є ІСО стандарт (по ISO/IEC 25010 9 категорій в кжній по декілька атрибутів), є класифікація від майкрософт, e СЕІ своя класифікація.
2) Не ясно (точніше не хотілося б бути правим) чому за основу була вибрана описана на сайті компанії syndicode. Чим вони експертніші за МС чи СЕІ?

3) Software Architecture Quality Attributes не є атрибутами якості архітектури проекту. Ми не оцінюємо за ціми показниками архітектуру. Якісні атрибути — є вихідними даними для побудови архітектури.
Quality Attributes — це атрибути якості програмного забезпечення.
І якісна архітектура проекту проховує їх відповідно до їх пріоритету.
Наприклад, те що ви називаєте Flexibility дехто міг би назвати Extensibility, не дуже часто є ключовим атрибутом. Власне типова помилка людей з великим саме девелоперським досвідом — це зависока їх пріоритизація разом з Reusability.

UPD
У АРК42 є своя класифікація quality.arc42.org , але там немає Maintainability

Дякую за комент. Дуже правильні твердження з якими важко не погодитись. Дозвольте відповісти по пунктах:
1. Навів саме цифру в 12 що б бути консистентним з статтею за посиланням. Згоден що їх кількість ніде не затверджена і перелік різниця в залежності від джерела... певно було б не зайвим це прописати)
2. Нічим. Просто мені сподобалась подача матеріалу у них. А в рамках цієї статті гадаю їх компетенція достатня )
3. Підтримую це визначення. Зайшов я в статті саме з боку виявлення цих аттребутів на проекті бо набагато легше визначати проблемні місця (а значить і косяки при проектуванні, якщо воно було) коли проект вже готовий і коли ці місця всім очевидні. Але не маючи відомостей про такі аттребути досить важко сформулювати ці «визначення слабких місць» в щось більш-менш конкретне ніж «наітіє». Да і відомості про основні аттребути можуть допомогти побачити проблему на проекті. Тому гадаю оперування цими термінами для виявлення проблемних місць і закладання вектору для масштабного рефакторингу також доречним. Хоча 100% згоден що їх призначення — це бути визначеними саме при проектуванні архітектури )

Уточнюючи 3ій пункт:

Тобто я пропоную використовувати ці аттребути і визначати їх саме для формування вектору розвитку проекту і для створення підґрунття для прийняття рішень при рефакторінгу. Да і їх пріоритетність легше визначити коли проект уже деякий час живе і його бізнес-модель більш-менш сформована)

Тобто я пропоную використовувати ці аттребути і визначати їх саме для формування вектору розвитку проекту і для створення підґрунття для прийняття рішень при рефакторінгу.

Давайте в контексті УІ (бо у вас ФЕ бекграйнд наче):
Ми розробляємо софт для брокерів.
Ментейнабіліті та флексебіліті закриваються баблом — банально наймуть більше кращих розробників.
АСР — лейтенсі, перформанс, релаябіліті.
Скоріше за все, для того, щоб максимально швидко доставити необхідні дані (ще й консистенітні) до терміналу вам доведеться пожертвувати зрозумілістю коду і можливістю його розширяти. У вас будуть кастомні формати даних та протоколи поверх веб-сокетів. Реакт з редаксом просто не буде справлятись з об’ємами даних, які будуть на ФЕ через 30 хв роботи (у нас так було).
Тестабіліті (трейтій атрибут) вас теж цікавить лише в контексті релаябіліті. І якщо ви не зможете написати юніт чи інтеграційні тести, це теж можна закрити баблом — банально по 2 білд-агенти на розробника, щоб ганяти інтеграційні тести. А проблеми з сайдефектами вирішивати велитенськими логами, які девелопери будуть мануально переглядати.

Да і їх пріоритетність легше визначити коли проект уже деякий час живе і його бізнес-модель більш-менш сформована)

Тобто ви пропонуєте будувати архітектуру проекту (для початку побудови якої треба пріоритезовані списки якісних атрибутів) вже після побудови системи.

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

Мені здалось що ви подумали що я пропоную спочатку розробляти проекти як-небуть, а потім думати про аттребути і планувати архітектуру. Ні, це не так))
Я також думаю що краще спочатку спланувати — потім зробити, і планування повинно враховувати потреби проекту.

Втім, якщо так сталось що проект вже написаний. Ви бачите що на ньому багато проблем і хочете це виправити, з чого взагалі починати? Гасити пожежі, або ж рефакторити що доведеться і коли буде час? Гадаю це програшна стратегія.
Для мене планування рефакторингу проекту — перший і найважливіший крок. І ось коли сідаєш перед порожнім листком конфлюєнса чи ноушина, дуже складно трансформувати думку «спалити все і переписати заново» в щось корисне. І, як на мене, як перший крок в розробці такого плану\дизайну має бути визначення тих самих аттребутів. Так як проект вже деякий час існує і його бізнес-модель настоялась, такі аттребути мають бути більш-менш зрозумілими, а досвід роботи з кодовою базою дасть змогу ще точніше їх визначити за тими проблемами які існують і найбільше заважають.
Далі, після їх визначення, операючись на них, можна приймати подальші рішення )

Ви з цим не згодні?)

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

Погане у наступній фразі:

Тобто я пропоную використовувати ці аттребути і визначати їх саме для формування вектору розвитку проекту і для створення підґрунття для прийняття рішень при рефакторінгу.

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

Так, я їх обрав для прикладу і тільки. Кожен розробник має вирішувати що для проекту пріоритетне, а чим можна пожертвувати.

Мабуть варто цю фразу «для прикладу» додати в статтю )

Тобто я говорив за аттребути загалом, як перелік якостей, а не за якісь конкретні)

btw якби я працював на проекті який ви навели як приклад — я б думав в таку сторону:
1. Якщо софт для брокерів — він перш за все має бути відомовостійким. Якщо апка регулярно крашиться після релізів це буде бісити клієнтів які не змогли вчасно щось продати і такі проблеми буде не раціонально виявляти шляхом тестування на проді. Перш за все через те що страждає бренд ))
2. Якщо все вирішувати баблом, воно буде швидше закінчуватись. В часи в компанії дохід рахують в вагонах таке рішення може й буде працювати, а ось при першій же кризі буде дуже тяжко. Тому якщо сказати що півтора вагона бабла на місяць можна буде економити якщо витратити 3 вагона на те що б зробити оцю штуку краще — для майже будь-якого менеджера це буде раціональна пропозиція)

Якщо софт для брокерів — він перш за все має бути відомовостійким. Якщо апка регулярно крашиться після релізів

Так не буде релізу :) Буде болісне і довге тестування та фікс багів і стабільний код на виході (при тому, що ментейнабіліті і тестабіліті дуже погані)

2. Якщо все вирішувати баблом, воно буде швидше закінчуватись

Якось пацани викидали на розробку софта кілька лямів в рік, для того щоб їм нарахували __лише__ 10 лямів штрафних санкцій. І ніхто не планував робити реліз, бо (далі переклад цитати) «ефорт на реліз та ризики не вартують тих копійок»

Якщо ми говоримо за фронтенд, то я дуже легко можу уявити як мануальщики пропустили який рідкий випадок і на проді n користувачів зловить бажину типу «can’t get name from undefined». І ось зробити так що б ця бажина не поклала апку — досить доцільно, адже навіть на 100% (утопія) покритий тестами проект не гарантує що таке не трапиться на проді )

Втім якщо овнер вважає що краще найняти n розробників для мануального парсингу лгів — для мене це був би червоний флаг для відкриття свого резюме на джинни))))

Але про овнерів і манагерів в 2ій частинні статті, сподіваюсь скоро вийде ))

Дякую за статтю!

Розрослий MVP.

Це зветься — ентропія коду, може статись для будь чого. Це насправді не найгірший варіант, є варіанти сильно гірше, наприклад код з Бангалору який навмисно писали щоб було по більше операторів. Код 0-вих новачків і т.д. і т.п. ІМХО там нема чого рефакторити.

Згоден що вручну обфускований код краще переписати заново, ніж рефакторити)

Щодо MVP — я навів цей приклад свідомо, бо це місце приняття компромісних рішень в умовах динамічно змінюваних бізнес-правил\запитів. З мого досвіду в таких проектах неможливо й один файл відкрити що б не почати думати як можна було б написати краще)
Тому, імхо, такі проекти — прям кландайк для можливостей рефакторингу... ну і мабуть найпоширеніші серед тих кому буде цікава стаття )

Найгірший варіант це поробка на Delphi 6, яку свого часу написали на колінці щоб швидко щось автоматизувати. І потім цей проект розростався поки не став core системою величезного ентерпрайзу.
Рефакторити це неймовірно дорого. Просто викинути це ще дорожче

Доречі також кейс)))

Були в моїй кар’єрі проекти які просто залишали помирати на «підтримці» доки вони приносять дохід, з розумінням що відрефакторити неможливо, а вдосконалювати — задорого )

Просто викинути це ще дорожче

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

Ну щодо того прикладу що навів сам цією платформою не займався. А розробники там здебільшого були з інших стеків, яких пересадили на Delphi бо на ринку цих розробників шукати не реально. І вони самі звільнялись через це. Тому шарили їх з іншими проектами щоб не так сумно їм було

Підписатись на коментарі