Франкенштейн у програмуванні — що це, причини та профілактика

Автор: IT Sectr Опубліковано: 2026-07-26 Час читання: 10 хв

Франкенштейн у програмуванні — це код, зібраний із несумісних частин різних технологій, стилів та архітектур. За даними дослідження ThoughtWorks Technology Radar (2024), 28% великих проєктів містять ознаки синдрому Франкенштейна — архітектурної еклектики, що виникає за відсутності єдиного технічного бачення. За аналогією з романом Мері Шеллі, такий код працює, але його підтримка перетворюється на кошмар.

Головне

  • Франкенштейн — антипатерн, за якого система збирається з різнорідних, погано сумісних компонентів
  • Основні причини: відсутність архітектора, злиття проєктів, «креативність без меж»
  • Проблема — кожен компонент вимагає знання своєї технології, а взаємодія непередбачувана
  • Рефакторинг Франкенштейна потребує уніфікації технологічного стека та виділення чітких меж
  • Architecture Decision Records та RFC — найкращі інструменти профілактики

Що таке Франкенштейн у програмуванні

Франкенштейн (Frankenstein code, Frankenstein pattern) — це антипатерн, за якого програмна система збирається з частин, не призначених для спільної роботи. Як монстр Франкенштейна, такий код може функціонувати, але він потворний, непередбачуваний і небезпечний за найменших змін.

Термін прийшов із літератури: у романі Мері Шеллі «Франкенштейн, або Сучасний Прометей» (1818) учений створив живу істоту з фрагментів тіл різних померлих людей. У програмуванні аналогія точна — розробники беруть шматки різних фреймворків, бібліотек, мов і склеюють їх «на живу нитку», отримуючи робочий, але жахливий результат.

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

Франкенштейн vs мікросервіси

Мікросервісна архітектура допускає використання різних технологій для різних сервісів, але за умови чітких меж і стандартизованих протоколів взаємодії. Франкенштейн — це хаотичне змішування без меж: REST і GraphQL в одному контролері, дві ORM в одному модулі, SQL і NoSQL для однієї сутності.

Чому виникає синдром Франкенштейна

Відсутність технічного лідера або архітектора — першопричина. Коли в проєкті немає людини, яка відповідає за цілісність архітектури, кожен розробник обирає інструменти «під себе». Один любить Spring, другий — Guice, третій — власний DI. Результат — архітектурний вінегрет.

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

Корпоративні поглинання — третій сценарій. Компанія А купила компанію Б і хоче інтегрувати її продукт у свій. Замість переписування — склейка через API, спільні бази даних і милиці. За рік система перетворюється на монстра, якого ніхто не розуміє.

ПричинаОписТиповий результат
Немає архітектораКожен розробник обирає свій стек3 різні HTTP-клієнти в одному модулі
Злиття проєктівДва продукти склеюються в одинДві ORM, два способи логування
M&AПоглинання компанії з її продуктомГібрид із різних архітектур і стилів
ЕкспериментиВпровадження нових технологій без стратегіїJava 8 + фічі Java 21 в одному файлі
Політичні рішенняНав'язування технології зверху без урахування контекстуEnterprise-фреймворк для простого скрипта

Фактор «креативності»

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

Приклади Франкенштейна в реальних проєктах

Класичний приклад — використання кількох ORM в одному застосунку. Частина модулів використовує Hibernate, частина — MyBatis, а частина — прямі JDBC-запити. Транзакції стають некерованими, кеш — неузгодженим, а новий розробник не знає, який підхід обрати для нової фічі.

Другий приклад — змішування архітектурних стилів. У контролері REST API трапляються виклики SOAP-сервісів, прямі SQL-запити, звернення до файлової системи та генерація HTML. Такий застосунок неможливо тестувати, розширювати чи документувати.

Третій приклад — технологічний стек, де Python використовується для бекенду, Node.js — для мікросервісу, C# — для десктопного клієнта, а Java — для Android-застосунку, при цьому вся бізнес-логіка розмазана між ними без чіткого розподілу відповідальності.

javascript
// франкенштейн — змішані стилі та технології
// callbacks, Promises та async/await разом

// callbacks
db.query("SELECT * FROM users", function(err, rows) {
  if (err) handleError(err);
  // Promise усередині callback
  fetch("/api/data").then(function(data) {
    // async/await усередині then
    (async () => {
      const result = await processData(data);
      sendResponse(result);
    })();
  });
});

// чистий код — єдиний стиль async/await
async function getUserData(userId) {
  const user = await db.query("SELECT * FROM users WHERE id = ?", [userId]);
  const data = await fetch("/api/data/" + userId);
  return await processData(user, data);
}

Франкенштейн на рівні даних

Одна база даних використовується одночасно як SQL-реляційна (з нормалізацією) і як NoSQL-документо-орієнтована (з JSON-колонками). Частина запитів іде через ORM, частина — через збережені процедури, частина — через прямий SQL із коду. Схема БД не документована, міграції конфліктують.

Наслідки Франкенштейн-коду

Складність онбордингу — перший наслідок. Новий розробник має знати 5 мов, 3 фреймворки, 2 архітектурні стилі, щоб розуміти, як працює система. Онбординг затягується з тижнів до місяців. За даними LinkedIn (2023), проєкти з технологічною еклектикою втрачають нових співробітників у 2 рази частіше.

Непередбачуваність поведінки — другий наслідок. Зміна в Python-мікросервісі може несподівано зламати Java-модуль, бо вони використовують спільну БД без чітких контрактів. Налагодження таких проблем вимагає одночасного знання всіх технологій у стеку.

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

Технічний борг Франкенштейна

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

Як уникнути створення монстра

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

Другий — впровадити процес Architecture Decision Record (ADR). Будь-яке значне архітектурне рішення (вибір БД, фреймворку, протоколу) документується у вигляді короткого тексту: контекст, розглянуті альтернативи, ухвалене рішення, наслідки. ADR зберігаються в репозиторії та доступні всій команді.

Третій — встановити принцип «одне завдання — один інструмент». Для HTTP-запитів — один клієнт. Для ORM — одна бібліотека. Для логування — один фреймворк. Винятки допускаються лише через ADR з обґрунтуванням. Якщо в проєкті вже є Axios — не додавайте fetch, якщо є SLF4J — не пишіть через System.out.

  • Архітектор із правом вето на нові технології
  • Architecture Decision Records для кожного значущого вибору
  • Єдиний стек для кожного завдання — один HTTP-клієнт, одна ORM
  • RFC для великих змін з обговоренням усією командою
  • Технологічний радар для відстеження того, що можна впроваджувати

Політика експериментальних технологій

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

Як рефакторити наявний Франкенштейн

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

Стандартизація — другий крок. Оберіть один інструмент для кожного завдання. Наприклад: тільки Hibernate для ORM, тільки SLF4J + Logback для логування, тільки REST для API. Задокументуйте стандарт в ADR. Почніть заміну з модулів, де еклектика приносить найбільше проблем.

Стратегія Parallel Run — третій крок. Старий і новий інструменти працюють паралельно, поки новий не доведе свою надійність. Наприклад, старий HTTP-клієнт і новий працюють одночасно, але новий — лише для частини запитів. Після періоду стабілізації старий видаляється.

java
// франкенштейн — три HTTP-підходи в одному проєкті
// Модуль A: OkHttp
OkHttpClient client = new OkHttpClient().newCall(request);

// Модуль B: RestTemplate (Spring)
restTemplate.getForObject(url, String.class);

// Модуль C: java.net.HttpURLConnection
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();

// єдиний підхід: RestTemplate для синхронного, WebClient для реактивного
@Autowired
private RestTemplate restTemplate;

public String callApi(String url) {
    return restTemplate.getForObject(url, String.class);
}

Роль технічного лідера в профілактиці

Технічний лідер — головний інструмент боротьби з Франкенштейном. Не менеджер, не архітектор у вежі зі слонової кістки, а практикуючий розробник, який пише код, рев'юїть PR та ухвалює архітектурні рішення. Без такої людини проєкт неминуче скочується в технологічну еклектику.

RFC (Request for Comments) — процес, запозичений із Open Source-спільнот. Перед впровадженням будь-якої значущої технології автор пише RFC: проблема, пропоноване рішення, альтернативи, план впровадження. Команда обговорює, голосує, ухвалює або відхиляє. RFC створює прозорість і запобігає «тихим» архітектурним рішенням.

Технологічний радар (Technology Radar від ThoughtWorks) — інструмент категоризації технологій: Adopt, Trial, Assess, Hold. Команда регулярно переглядає радар і оновлює статуси. Це допомагає відрізняти «модне» від «корисного» та уникати впровадження неперевірених технологій у критичний код.

Принцип узгодженості

Найважливіша якість архітектури — узгодженість (consistency). Навіть не найкращий інструмент, який використовується у всьому проєкті, кращий, ніж найкращий інструмент, який використовується лише в одному модулі. Узгодженість знижує когнітивне навантаження, спрощує онбординг і робить код передбачуваним.

Часто задавані питання

Чим Франкенштейн відрізняється від використання polyglot persistence?

Polyglot persistence — усвідомлене використання різних БД для різних завдань (PostgreSQL для транзакцій, Redis для кешу, Elasticsearch для пошуку). Франкенштейн — хаотичне змішування без стратегії. Різниця в наявності архітектурного рішення: polyglot — це план, Франкенштейн — його відсутність.

Чи може мікросервісна архітектура перетворитися на Франкенштейна?

Так, і це часта проблема. Коли кожен мікросервіс використовує свою мову, свою БД, свій протокол і свій підхід до розгортання без централізованих стандартів — виходить розподілений Франкенштейн. Для мікросервісів важливі спільні стандарти: єдиний протокол (REST/gRPC), спільний формат логів, централізоване observability.

Як переконати команду не використовувати нову технологію?

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

Як боротися з Франкенштейном в успадкованому проєкті?

Спочатку інвентаризація, потім стандартизація. Не намагайтеся переписати все одразу. Виділіть один шар (наприклад, HTTP-клієнти або логування), оберіть єдиний інструмент, напишіть ADR і мігруйте поступово. Метод Strangler Fig — замінюйте старі компоненти новими по одному, без зупинки роботи застосунку.

Скільки технологій оптимально для одного проєкту?

Чим менше, тим краще. Ідеально — одна мова, один фреймворк, одна БД, один спосіб логування. Реалістично — 2–3 мови (за чіткого розподілу), 1–2 БД, 1–2 фреймворки. Кожна додаткова технологія збільшує когнітивне навантаження команди та вартість підтримки.

Підсумки

  • Франкенштейн — антипатерн, за якого система зібрана з різнорідних несумісних компонентів
  • Основні причини: відсутність архітектора, злиття проєктів, безконтрольні експерименти
  • Наслідки — складний онбординг, непередбачувана поведінка, проблеми з безпекою
  • ADR та RFC — ключові процеси для запобігання архітектурній еклектиці
  • Принцип «один інструмент на завдання» — основа профілактики
  • Рефакторинг починається з інвентаризації та стандартизації технологічного стека
  • Узгодженість архітектури важливіша, ніж «найкращий інструмент» для однієї підзадачі

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також