Legacy и миграции

·5 мин чтения·Обновлено

Anti-Corruption Layer: как подключить legacy или внешний сервис, не впустив его модель внутрь

В учётной системе задание закрыто, но оборудование ещё нельзя выдать клиенту. Как подключить такой источник, не распространив неверное обещание по всему продукту?

Клиентский кабинет получает из старой системы ремонта статус «закрыто» и показывает: «Оборудование готово к выдаче». Между тем мастер завершил только своё задание, а итоговая проверка ещё не пройдена. Поле передали без ошибки. Ошиблись в значении.

Anti-Corruption Layer, сокращённо ACL, защищает внутреннюю модель от такого переноса чужих понятий. Здесь «corruption» означает искажение модели, а не вредоносный код или взятки. Слой понимает внешний контракт и предоставляет нашему приложению сведения в его собственных терминах. Но он не способен получить из ответа факт, которого поставщик вообще не сообщает.

Переименовать поле мало

Для кабинета полезны отдельные состояния: работа мастера завершена, проверка пройдена, выдача разрешена. Если внешний статус описывает только первое, нельзя автоматически вывести третье. Понадобится дополнительный источник, уточнение у поставщика или честное промежуточное состояние на экране.

Именно защиту смысла, а не только формата, описывает паттерн в Azure Architecture Center. Преобразование XML в JSON само по себе может оставаться обычной технической адаптацией. ACL нужен там, где способы описания работы действительно различаются.

Различия не обязательно означают плохую старую систему. Она могла обслуживать мастера, которому достаточно состояния своего задания. Клиентский кабинет решает другую задачу. Ему нужен собственный контракт, а не универсальное объяснение, почему один чужой статус должен подходить всем.

Сначала составить таблицу смысла

Для каждого используемого состояния запишите, какое основание оно даёт нашему продукту. Что подтверждено? Чего мы ещё не знаем? Какую операцию можно выполнять дальше? В случае ремонта завершение задания может разрешать запрос проверки, но не отправку уведомления о готовности.

Сопоставление должно включать отсутствующие и неизвестные значения. Новый статус поставщика нельзя молча считать успешным только потому, что программа его не распознала. Равно опасно превращать отсутствие сведений в отказ: клиент увидит отмену ремонта там, где система просто не получила обновление.

Нужны и правила для идентификаторов. Номер задания мастера может не совпадать с номером обращения клиента, а одному обращению соответствовать несколько заданий. Хранить связь полезно с указанием источника и области уникальности. Совпадение коротких номеров в двух организациях не должно объединять их документы.

Единицы измерения, часовые пояса и обязательность полей тоже относятся к контракту. Если срок указан без времени или без зоны, переводчик не должен выдумывать точность, которой нет. Решение о том, что обещать клиенту на основании таких данных, остаётся у владельца продукта.

Не прятать неопределённость под удобной ошибкой

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

Внутреннему приложению полезно различать подтверждённый отказ, временную недоступность и неизвестный результат. Для последнего нужен поиск операции по устойчивому идентификатору или другой предусмотренный способ сверки. Amazon Builders' Library объясняет, почему безопасные повторы зависят от контракта операции, а не только от задержки перед следующей попыткой.

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

Где заканчивается перевод и начинается второе приложение

Правила отображения чужой модели принадлежат границе. Правила скидки, гарантийного ремонта или компенсации клиенту — соответствующей части продукта. Если в адаптер постепенно переносится всё, что неудобно разместить иначе, он превращается в ещё одну бизнес-систему, только без признанного владельца.

ACL можно реализовать модулем внутри приложения. Отдельный сервис уместен, когда нужны самостоятельное сопровождение, масштабирование или повторное использование перевода. Но он добавляет сетевой переход и собственный отказ. Развёртывать новый компонент ради нескольких простых преобразований необязательно.

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

Перевод данных не выдаёт разрешение на их получение. Если общая интеграция имеет доступ к обращениям нескольких организаций, кабинет всё равно должен ограничивать выдачу текущим клиентом. Нельзя принимать чужой идентификатор из запроса как достаточное основание прочитать документ. Удобный внутренний контракт сохраняет границы доступа, а не скрывает их вместе с особенностями поставщика.

Испытать неудобный ответ до миграции

Соберите разрешённые для тестирования примеры: завершено только одно задание, проверки нет, номер повторяется у другого источника, появился неизвестный статус. Отдельно проверьте потерю ответа после успешной записи. Для каждого примера должно быть понятно, что увидит клиент и какая работа продолжится.

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

При замене системы сравните результат старого и нового перевода на одинаковых сценариях. Не отправляйте изменяющие команды одновременно двум поставщикам ради сравнения: это может выполнить действие дважды. Для чтения также нужны проверенные права и ограничения обращения с данными.

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