Перейти к содержанию

Архитектурные границы компонентов

Требования применяются к внутренней структуре запускаемых и публикуемых компонентов, разделяющих ответственность между проектными модулями и адаптерами. Они не предписывают число слоёв или именованный архитектурный паттерн. Уровни обязательности определены в корневом README.md.

В этом документе:

  • проектный модуль — именованная единица исходного кода с определяемыми статическими зависимостями;
  • прикладное правило — независимое от технологии входа решение о допустимости, результате, состоянии или обязательном эффекте операции;
  • прикладная граница — принадлежащий проекту контракт вызова прикладного правила;
  • адаптер — код, преобразующий контракт транспорта, хранилища, framework или внешнего provider в контракт прикладной границы либо обратно.

ARC-PAT-001. Обоснованная архитектурная абстракция

Уровень: SHOULD

Применяется к: добавлению проектного интерфейса, слоя или модуля, не заданного внешним контрактом

Новой архитектурной абстракции следует изолировать хотя бы одно фактически существующее различие:

  • внешний контракт или технологическую границу;
  • независимо проверяемое прикладное правило;
  • две фактически используемые реализации одного контракта;
  • направление зависимости, жизненный цикл или границу доступа, контролируемые статической проверкой.

У абстракции следует определять потребителя и реализацию. Абстракцию, которая только переименовывает вызов и не изолирует ни одно из перечисленных различий, добавлять не следует.

Обоснование

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

Проверка

  • сопоставление абстракции с одним из перечисленных различий;
  • поиск фактического потребителя и реализации;
  • сравнение с прямой реализацией без дополнительной границы;
  • architecture test направления зависимости, если граница его устанавливает.

Исключения

Extension point, обязательный для framework, и сгенерированный контракт MAY иметь одну реализацию, если их происхождение определяется dependency metadata или входом генератора.

ARC-PAT-002. Направление зависимости прикладной границы

Уровень: SHOULD

Применяется к: компоненту с прикладным правилом и адаптером транспорта, хранилища, framework или внешнего provider

Прикладное правило следует выражать через принадлежащие проекту входные, выходные и отказные контракты. Ему не следует требовать тип, lifecycle context, активное соединение или сессию адаптера для выполнения самого решения.

Адаптеру следует зависеть от прикладной границы и преобразовывать внешний контракт до её вызова и после получения результата. Прикладному правилу не следует зависеть от реализации адаптера.

Обоснование

Направление зависимости позволяет проверять правило без внешней инфраструктуры и менять технологию границы без изменения его семантики.

Проверка

  • статическая проверка import graph между прикладным правилом и адаптерами;
  • unit-тест правила без инициализации framework, сети или хранилища;
  • contract-тест преобразования входов, результатов и ошибок адаптера.

Исключения

Тип MAY быть сгенерирован из версионируемого проектного или публичного контракта, если он не требует lifecycle context, соединения или сессии конкретного адаптера и его совместимость проверяется автоматически.

Компонент, который только проверяет и передаёт внешний контракт без прикладного правила, находится вне области требования.

ARC-PAT-003. Единый путь применения прикладного правила

Уровень: MUST

Применяется к: операции, выполняющей изменение состояния или внешний эффект после проверки доступа, инварианта, идемпотентности либо транзакционного условия

Каждое применимое прикладное правило должно иметь единственное место применения за прикладной границей. Каждая поддерживаемая точка входа, способная инициировать эффект, должна проходить через это место до выполнения эффекта. Адаптер не должен изменять состояние или выполнять внешний эффект по пути, обходящему прикладное правило.

Проверка синтаксиса и формы входа MAY выполняться отдельно в каждом адаптере, но не должна задавать альтернативную семантику доступа, инварианта, идемпотентности или транзакционного условия.

Обоснование

Дублирование правила между HTTP handler, consumer, job или UI создаёт пути, которые по-разному защищают доступ и целостность данных.

Проверка

  • перечисление поддерживаемых точек входа и трассировка вызова общей прикладной границы;
  • статический запрет прямого доступа входного адаптера к реализации эффекта;
  • негативный тест каждой точки входа: отклонённое правило не создаёт эффект.

Исключения

Миграционная или repair-операция MAY использовать отдельное правило только по ADR, определяющему её назначение, доступ, входные данные, аудит и срок удаления. Read-only техническая операция без перечисленного эффекта находится вне области требования.

ARC-PAT-004. Ациклические зависимости проектных модулей

Уровень: SHOULD

Применяется к: компоненту с двумя и более проектными модулями и статическими зависимостями между ними

Граф статических зависимостей проектных модулей следует сохранять направленным и ациклическим. Runtime-вызов callback, событие или переданная реализация MAY иметь обратное направление, если они не создают обратную статическую зависимость.

При обнаружении цикла следует изменить владение общим контрактом или объединить части, которые не имеют независимой границы.

Обоснование

Цикл скрывает владельца контракта, связывает независимые изменения и мешает проверять направление зависимостей.

Проверка

  • автоматическое построение import или module dependency graph;
  • architecture test, отклоняющий добавление цикла;
  • сборка модулей в топологическом порядке, если toolchain поддерживает отдельную сборку.

Исключения

Сгенерированный взаимно-рекурсивный тип MAY образовывать цикл внутри изолированного generated-кода, если вход генератора версионируется, а рукописные проектные модули остаются ациклическими.