Франкенштейн в программировании — что это, причины и профилактика

Автор: 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
// frankenstein — mixed styles and technologies
// callbacks, Promises, and async/await combined

// callbacks
db.query("SELECT * FROM users", function(err, rows) {
  if (err) handleError(err);
  // Promise inside callback
  fetch("/api/data").then(function(data) {
    // async/await inside then
    (async () => {
      const result = await processData(data);
      sendResponse(result);
    })();
  });
});

// clean code — unified async/await style
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
// frankenstein — three HTTP approaches in one project
// Module A: OkHttp
OkHttpClient client = new OkHttpClient().newCall(request);

// Module B: RestTemplate (Spring)
restTemplate.getForObject(url, String.class);

// Module C: java.net.HttpURLConnection
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();

// unified approach: RestTemplate for sync, WebClient for reactive
@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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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