open atlas
↑ К треку
Архитектурные паттерны ARCH · 11 · 01

Architecture Decision Records

ADR фиксирует одно архитектурное решение — контекст, силы, выбор и последствия — чтобы будущие инженеры знали ПОЧЕМУ, а не только что было решено. Легковесный формат, версионируемый рядом с кодом, неизменяемый после принятия: superseded, но не удалён.

ARCH Senior ◷ 20 min
Уровень
ОсновыJuniorMiddleSenior

Через шесть месяцев после того, как B2B биллинговая платформа переключилась с REST-взаимодействия между модулями на событийную модель, новый инженер спросил — почему. Команда три дня просматривала Slack, Confluence и pull request’ы и нашла фрагменты: тред «обсуждали на мартовском митинге», описание PR «переходим на события», Jira-тикет «технический долг». Никто не смог восстановить силы, которые обусловили решение: болтливые REST-вызовы, вызывавшие каскадные отказы при биллинговых запусках; три рассмотренные альтернативы; причину, по которой отклонили очередь сообщений в пользу доменных событий; трейдоффы, которые сознательно приняли. Когда проявился режим отказа, с которым событийная модель не справлялась, команда снова начала спорить об исходном решении — без контекста. Двое хотели откатиться, двое — двигаться вперёд. Записи о том, что уже рассматривалось, не было.

Написать Architecture Decision Record занял бы тридцать минут. Вместо этого потребовалось три дня раскопок и неразрешённый архитектурный спор.

Что такое ADR и чем он не является

Architecture Decision Record — короткий документ, как правило одна-две страницы, фиксирующий одно значимое архитектурное решение. Формат предложил Майкл Найгард в 2011 году. Ключевой инсайт: само решение менее важно, чем обоснование — контекст, сделавший решение необходимым, силы, тянувшие в разные стороны, рассмотренные альтернативы и принятые последствия.

ADR — это не:

  • Проектный документ (он описывает, как что-то построено)
  • Документ требований (он описывает, что должно делаться)
  • Постмортем (он описывает, что пошло не так)
  • Живой документ (ADR неизменяем после принятия: он superseded, но не редактируется)

Формат Найгарда состоит из пяти разделов:

Заголовок. Короткая фраза в повелительном наклонении: «Использовать доменные события для межмодульного взаимодействия», а не «Решение о событийно-ориентированной архитектуре».

Статус. Proposed → Accepted → Superseded (by ADR-NNN) | Deprecated. Статус никогда не бывает «rejected» для принятых решений — они superseded, когда более новое решение их заменяет. Отклонённые предложения остаются Proposed ADR’ами, которые так и не были приняты.

Контекст. Силы и обстоятельства, сделавшие это решение необходимым. В чём была проблема? Какие ограничения существовали? Какова была текущая ситуация?

Решение. Сделанный выбор, изложенный прямо: «Мы будем использовать доменные события, публикуемые на внутрипроцессной шине, для всей кросс-модульной коммуникации».

Последствия. Принятые трейдоффы. Что стало проще? Что стало сложнее? Какие новые риски введены?

Почему ПОЧЕМУ — это ценность

Рассмотрим две записи об одном решении:

Запись A (коммит-сообщение): «Переключить кросс-модульное взаимодействие на доменные события».

Запись B (ADR): «Контекст: модуль billing вызывает REST API модуля ordering синхронно во время генерации инвойсов. При всплесках объёма заказов это вызывает каскадные таймауты. Мы оценили три варианта: (1) добавить очередь между REST-вызывающими, (2) переключиться на доменные события на внутрипроцессной шине, (3) переработать billing так, чтобы он владел read-моделью данных заказов. Мы отклонили (1), потому что он добавляет операционную сложность (брокер для управления) без устранения зацепления. Мы отклонили (3), потому что ownership данных заказов в billing нарушает принципы владения данными (ADR-004). Решение: принимаем доменные события на внутрипроцессной шине (без брокера). Последствия: кросс-модульные вызовы становятся асинхронными; логика billing должна обрабатывать события, приходящие не по порядку; мы принимаем, что billing не может немедленно подтвердить текущий статус заказа».

Запись B позволяет будущему инженеру понять: (a) почему проблема существовала, (b) что рассматривалось и отклонялось и почему, (c) какие трейдоффы были сознательно приняты.

Why this works

Почему ADR должен фиксировать отклонённые альтернативы? Потому что именно они предотвращают повторное открытие вопроса. Без записи о том, почему вариант (1) был отклонён, следующий инженер, столкнувшись с проблемой, самостоятельно предложит вариант (1). Имея запись, обсуждение начинается с «мы отклонили это по причине X — изменилось ли X?», а не с нуля. Отклонённый путь столь же информативен, что и выбранный.

Викторина

У команды биллинговой платформы есть принятый ADR (ADR-007) «использовать доменные события для кросс-модульного взаимодействия». Год спустя профилирование производительности показывает, что внутрипроцессная шина создаёт узкое место при 50 000 конкурентных заказов. Старший инженер предлагает заменить её Kafka-брокером. Как правильно поступить с ADR'ами?

ADR как артефакт первого класса: система контроля версий и расположение

Легковесный формат ADR специально разработан для хранения рядом с кодом в системе контроля версий. Исходное предложение Найгарда помещает их в doc/arch/adr-NNN-title.md. ThoughtWorks Radar (2016) включает Lightweight Architecture Decision Records в список техник, рекомендованных к внедрению, именно потому, что они дёшевы и версионируемы.

Преимущества совместного хранения ADR’ов с кодом:

  • История изменений: когда меняется код, история ADR показывает, когда и почему было принято решение, коррелируемое с коммитом реализации.
  • Обнаруживаемость: инженеры, изучающие кодовую базу, находят ADR’ы там, где работают (в репозитории), а не в вики, которая может устареть.
  • Workflow pull request’ов: ADR можно предложить в pull request’е, рассмотреть вместе с изменением реализации и слить при принятии решения.
  • Долговечность: вики дрейфуют, страницы Confluence устаревают, Slack-треды архивируются. ADR в репозитории живёт столько, сколько существует кодовая база.
lesson.inset.note

Формат ADR намеренно минимален. Некоторые команды добавляют разделы (таблицы за/против, оценки рисков, ссылки на RFC-обсуждения). Это нормально, пока присутствует основная информация: контекст, решение, последствия. Формат Найгарда — минимум, а не максимум. Провальный режим — усложнить формат до такой степени, что написание ADR’ов становится настолько обременительным, что никто их не пишет. Двухабзацный ADR бесконечно лучше отсутствия ADR.

Викторина

Команда хранит архитектурные решения в Confluence. Инженер утверждает, что Confluence лучше ADR'ов в репозитории, поскольку предлагает богатое форматирование, поиск и комментарии. Старший инженер не согласен. Каков наиболее важный структурный аргумент против Confluence для записей решений?

Какие решения требуют ADR

Не каждое решение нуждается в ADR. Сигнал: потребовалось бы опытному инженеру, присоединившемуся к команде через два года, знать, почему это решение было принято — и смог бы он это понять из кода?

Решения, требующие ADR:

  • Выбор архитектурного стиля (событийно-ориентированный vs request-response, modular monolith vs микросервисы)
  • Значимые технологические выборы (конкретное хранилище событий, брокер сообщений, ORM)
  • Отклонённые альтернативы, которые скорее всего будут предложены снова («мы рассматривали X и отклонили, потому что…»)
  • Решения с неочевидными последствиями или принятыми трейдоффами
  • Решения, ограничивающие будущие опции («мы не сможем перейти на X, не переделав Y»)

Решения, не нуждающиеся в ADR:

  • Рутинные решения реализации (соглашения об именовании, структура файлов внутри модуля)
  • Идиоматические паттерны фреймворка (использование DI, потому что фреймворк его использует)
  • Решения, очевидные из кода и домена

Пример для биллинговой платформы: «Использовать PostgreSQL» вероятно не требует ADR, если команда — Rails-шоп с PostgreSQL по умолчанию. «Использовать PostgreSQL event sourcing вместо специализированного хранилища событий типа EventStoreDB» — точно требует ADR, поскольку есть неочевидные силы (операционная привычность к PG, стоимость эксплуатации EventStoreDB, проблема удаления при GDPR), которые будущие инженеры не смогут вывести из кода.

Викторина

Технический лид биллинговой платформы просматривает список кандидатов на ADR и находит четыре варианта. Какой из них наиболее явно требует ADR?

Вспомните перед уходом
  1. 01
    Каковы пять разделов формата ADR по Найгарду и почему раздел «Контекст» наиболее важен?
  2. 02
    Каков жизненный цикл статуса ADR и почему принятые ADR'ы никогда не удаляются и не редактируются?
  3. 03
    Почему ADR'ы должны храниться в репозитории кода, а не в вики или системе управления проектами?
Итог

Трёхдневные «раскопки» команды биллинговой платформы — восстановление решения, принятие которого заняло час — это режим отказа, который ADR’ы предотвращают. Журнал решений — не бюрократия; это институциональная память, сделанная явной и долговечной.

Формат намеренно минимален: контекст, решение, последствия. Неизменяемость намеренная: принятые ADR’ы superseded, а не редактируются. Расположение намеренное: рядом с кодом в системе контроля версий, там, где работают инженеры и где запись переживёт любую вики.

Важнейшая часть ADR — отклонённые альтернативы. Без них каждый инженер, столкнувшийся с той же проблемой, заново предложит те же альтернативы. С ними команда может начать с существующего анализа и спросить: «Достаточно ли изменился контекст, чтобы пересмотреть это?»

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

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

Примени это

Примени этот урок в реальном проекте.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources4
expand
  1. 01
  2. 02
  3. 03
  4. 04

Trademarks belong to their respective owners. Editorial reference only.