Гнучка модульна архітектура VIPER для iOS з генераторами коду

Застосунок зростає, і звична схема шарів починає гальмувати збірку та випуск оновлень. Ми проєктуємо та впроваджуємо модульну архітектуру VIPER для iOS під ключ: розбиваємо проєкт на незалежні модулі, знімаємо зв’язність і прискорюємо збірку кратно. Команда отримує каркас, який витримує зростання продукту та зміну розробників.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Гнучка модульна архітектура VIPER для iOS з генераторами коду
Складний
~3-5 днів
Часті запитання

Що дає модульний каркас: швидкість збірки та передбачуваність

Модульний каркас за схемою VIPER розбиває застосунок на незалежні модулі, де екран — це набір ізольованих шарів: представлення, логіка, робота з даними.

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

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

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

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

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

Режими організації шарів VIPER: порівняння підходів

Шари VIPER можна зібрати по-різному, і різниця видна не на першому екрані, а на двадцятому — коли правка одного сценарію тягне за собою View, Router і весь набір тестів.

Ключове питання: де проходять межі модулів і хто володіє контрактами — протоколами Presenter-а, Interactor-а і Router-а.

Варіант Коли підходить Обмеження
Ручні контракти всередині одного модуля 2–5 екранів, короткий строк Ручне копіювання, шари розходяться, тести дублюються
Генерація за шаблонами Десятки однотипних екранів Шаблон диктує структуру, генератор треба оновлювати на живому проєкті
Окремо зібрані модулі Кілька команд, повторне використання Дорожчий старт, суворі правила версій контракту
Спільний шар контрактів і модулів Великий продукт із потоками Без дисципліни спільний шар розростається

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

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

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

Етапи переведення застосунку на модульну схему

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

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

Порядок робіт виглядає так.

  1. Аудит залежностей. Збираємо карту зв’язків: де логіка розміщена в шарі представлення, які класи тягнуть за собою половину проєкту, де цикли й приховані звернення до спільного стану. На виході — перелік вузлів і черговість їхнього розпилу.
  2. Схема модулів і план переведення. Визначаємо межі: що стає самостійним модулем, що йде в спільний шар, які інтерфейси публічні. План переведення розбитий на хвилі — по одному-два модулі за реліз, щоб зміни залишалися осяжними.
  3. Налаштування генераторів коду. Заводимо шаблони модуля — представлення, інтерактор, презентер, сутність, маршрутизатор — з єдиними іменами та структурою папок. Новий модуль створюється командою, а не копіюванням сусіднього, тому різнобій між ділянками не накопичується.
  4. Пілотний модуль. Одну незалежну ділянку переводимо повністю за новою схемою та вбудовуємо в застосунок без зміни поведінки. Пілот показує реальну вартість кроку й те, скільки часу економлять генератори.
  5. Регресійна перевірка. Прогоняємо автотести на інтерактори та презентери, проходимо вручну критичні сценарії й порівнюємо поведінку до та після. Окремо фіксуємо час збірки й розмір артефактів — за ними видно, що модульність працює, а не лише описана.
  6. Передача документації та навчання команди. Віддаємо схеми модулів, правила меж, чек-листи перевірки коду та інструкцію з генераторів. Розбираємо все на живому коді, щоб команда далі переводила модулі своїми силами.

Що залишається в команди після передачі проєкту

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

  • Документація щодо модулів — призначення, входи й виходи, зв’язки з шарами VIPER-модуля; видно, що можна змінювати ізольовано, не зачіпаючи решту застосунку.
  • Шаблони й налаштування генерації — заготовки модулів і конфігурація інструментів, що створюють новий код за ухваленим стандартом; шаблон правиться в одному місці, і наступні модулі народжуються узгодженими.
  • Карта залежностей — схема зв’язків модулів, щоб новий функціонал не перетворював архітектуру на клубок.
  • Правила рев’ю коду — чек-лист перевіряльника: межі шарів, обробка помилок, покриття перевірками, домовленості щодо іменування.
  • Порядок випуску версій — шлях від гілки до публікації в магазинах застосунків: хто підтверджує, як готується опис змін, як відкочується невдалий реліз.
  • Інструкції для нових інженерів — оточення, точки входу, типові завдання першого тижня; вихід на самостійні правки займає дні, а не місяці.

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

Кейс: скоротили час збірки та прибрали клас відмов

Кейс мобільного застосунку на Swift: на початку робіт він збирався єдиною збіркою, де будь-який екран тягнув за собою весь код. Правка в одному місці запускала перезбирання всього проєкту, і цикл перевірки займав хвилини, яких у команди не було.

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

Переведення на модулі

Ми розклали застосунок на шари за схемою VIPER — екран, взаємодія, сутність, представлення, маршрутизація — і зафіксували контракти між ними. Генератори коду створюють каркас нового модуля й заготовки тестів, тому розробник одразу пише логіку, а не відтворює однотипні файли. Збірка стала інкрементальною: зміна в одному модулі не тягне за собою решту.

Цифри до та після

Повна збірка скоротилася втричі, збірка після типової правки — з десятків секунд до одиниць. Частка відмов на стиках модулів упала з 30% до 6%: контракти перевіряються на етапі збірки, а не на тестуванні й не на релізі.

Трудовитрати на доопрацювання нового екрана — 2 дні замість 1,5 тижня, бо структура, навігація та тести вже згенеровані. Відкат окремого модуля тепер теж не потребує перезбирання всього застосунку.

Що робити, якщо моноліт уже розгорнуто і переписувати не можна

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

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

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

Поступове впровадження модулів виграє у повного переписування за ризиками.

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

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

Технічні сумніви: тести, залежності, найм під схему

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

Як тестувати шари окремо?

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

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

Що робити із залежностями між модулями?

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

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

Чи потрібен окремий інженер під підтримку?

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

Як швидко новий розробник входить у проєкт?

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

Обговоримо задачу та повернемося з планом робіт

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

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

Після звернення ми розбираємо ситуацію та повертаємося з оцінкою й планом робіт.

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

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

Наші компетенції:

Останні роботи

  • Розробка мобільного додатка для компанії FEEDME
    Розробка мобільного додатка для компанії FEEDME
    1010
  • Розробка мобільного додатку для компанії XOOMER
    Розробка мобільного додатку для компанії XOOMER
    903
  • Розробка мобільного додатку для компанії RHL
    Розробка мобільного додатку для компанії RHL
    1332
  • Розробка мобільного додатку для компанії ZIPPY
    Розробка мобільного додатку для компанії ZIPPY
    1180
  • Розробка мобільного додатку для компанії Affhome
    Розробка мобільного додатку для компанії Affhome
    1107
  • Розробка мобільного додатку для компанії FLAVORS
    Розробка мобільного додатку для компанії FLAVORS
    714