Домены и команды

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

Shared Kernel: когда двум командам выгоднее разделить часть модели, чем дублировать её

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

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

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

Договориться о небольшом общем смысле

Shared Kernel — явно выделенная часть модели и связанной реализации, которую команды поддерживают совместно. В справочнике Эрика Эванса подчёркнуты небольшая граница, согласование изменений и регулярная интеграция результатов. Совместное владение здесь является частью решения, а не побочным эффектом установки пакета.

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

Обычная библиотека журналирования от этого не становится Shared Kernel: общая техническая функция не обязательно выражает совместную предметную модель. И наоборот, ядро не обязано сводиться к пакету классов. Участники могут явно делить часть схемы данных, но тогда принимают и последствия совместного изменения этой схемы.

Что именно обещает совпадение

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

Общий код не выравнивает разные входные данные. Предложение могло использовать предварительные размеры, а счёт — уточнённые. Поэтому для спорной операции полезно сохранять, какие сведения и какая версия правила участвовали в расчёте. Иначе одинаковая библиотека только усложнит объяснение: «у нас же везде один алгоритм».

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

Общая библиотека не требует одновременного выпуска всего продукта

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

Semantic Versioning помогает обозначать совместимые и несовместимые изменения опубликованного API. Номер версии не доказывает правильность поведения. Метод может принимать те же аргументы и возвращать тот же тип, но иначе рассчитывать результат. Для потребителей это может быть существенным нарушением контракта.

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

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

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

Совместная модель не означает общие права на все данные

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

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

Не стоит также переносить расчёт в удалённый сервис только ради слова «единый». Это централизует выполнение, но добавит сетевую зависимость и обязанность эксплуатировать сервис. Иногда такая граница оправдана. Иногда компактный пакет с понятными версиями обходится дешевле. Выбор определяется нужной согласованностью и возможностями команд.

Когда общее ядро перестаёт быть общим

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

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

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