Около десяти лет назад мы в CUSTIS реализовали систему распределения товара для «Спортмастера». Со времени ее запуска изменилось многое: корректировались цели заказчика, менялись возможности и потребности рынка, появились новые способы автоматизации. Но на протяжении всех этих лет система дорабатывалась, поддерживалась и настраивалась нами, чтобы оставаться максимально удобной и эффективной для заказчика.  В этой статье мы расскажем о себе, заказчике, системе и требуемых доработках. И о том, почему мы выбрали именно тот подход к проектированию архитектуры, который применили. И почему наше решение было оптимальным. В какой-то момент в компании «Спортмастер» возникла потребность на доработку одной из частей системы, но объем этой доработки был уже чуть больше среднего и с некоторым переосмыслением базовых понятий. Перед нами возникла дилемма: как выполнить доработку «красиво»? Сделать быстро и дешево на существующем технологическом стеке, на котором реализовали систему десять лет назад? Или на более современном, внедрение которого будет идти долго и дорого? Нужно было понять, оценить, обосновать плюсы и минусы обоих подходов. Нам не хотелось отталкиваться от сиюминутной выгоды и сворачивать на проторенную дорожку. Важно было учесть перспективу разных архитектурных решений на последующем жизненном цикле системы, дальнейший путь ее развития и модернизации. При этом конкретика бизнес-задач в данном случае была менее важна, чем общие характеристики системы. Такие, как длительность эксплуатации, стоимость владения, количество доработок, заложенных в модель развития, скорость устаревания технологического стека, последствия этого устаревания и т. п. Нам хочется поговорить о том, почему в общем-то стандартная задача по выбору архитектуры и технологического стека для модернизации успешно работающей долгое время системы является достаточно яркой и интересной. И почему это противоречие между «старым» и «новым» в нашем случае так критично и напряженно. Мы — это разработчики ПО из ИТ-компании CUSTIS. Работаем над созданием и сопровождением систем автоматизации бизнеса для его ведения и развития. Бизнес-заказчик описываемых ниже проектов — компания «Спортмастер», крупный ритейлер, который управляет сетью магазинов спортивных товаров. Фасилитатор нашей коммуникации с бизнес-заказчиком — ИТ-департамент «Спортмастера» Sportmaster Lab. В текущей концепции в «Спортмастере» товародвижением управляют одновременно несколько систем, для каждой отдельной области бизнеса — своя. Есть специализированная система, которая с необходимой степенью подробности реализует управление товарным запасом, учитывая основные бизнес-процессы. Управленческий товарный учет конвертируется в бухгалтерский при помощи сторонней системы «АИСТ». Ниже схематично показали, как ведется более подробный товарный учет для бизнес-потребностей конкретных департаментов «Спортмастера». Это отдельные специализированные системы (на рисунке — красная граница), а также отображение товарного запаса в проекции на бухгалтерский учет. Товарный запас внутри красной и черной границ эквивалентен.  Внутри красной границы системы не имеют общих остатков, товар «перетекает» из системы в систему. Мы прозвали такую схему «гамбургером», она была спроектирована совместно архитекторами «Спортмастера» и CUSTIS.  Рассматриваемая сегодня система называется «Модуль распределения товаров» (МРТ). Роль МРТ в этом «гамбургере» особая: модуль может управлять всем товаром «Спортмастера». Поэтому в нем отражается учет товара из специализированных систем, а также ведется учет и управление тем товаром, для которого еще не определен владелец — новым, общим. А в случае, когда нет специализированной системы, способной управлять таким товаром наиболее подходящим бизнесу способом, МРТ распределяет и их.  Процедуры работы в «Спортмастере» с товаром на внешней и внутренней цепях поставок существенно различаются. Доставка товара от поставщиков до распределительных центров ведется по-крупному: контейнерами, вагонами и пр. Дальнейшее движение товара по внутренней цепи — намного более подробно: коробками и штуками. Основные, но не единственные, процессы в МРТ — заранее распланировать ожидаемый к приходу с внешней цепи от поставщика товар, «поймать» его при поступлении. А дальше, сверившись с планами, распределить этот товар тому владельцу во внутренней цепи поставок, который его ожидает. Конечно, распределение носит виртуальный характер, существует только в системе: физически товар едет в контейнерах или лежит на складе, коробка к коробке. МРТ — далеко не единственная система, разработкой и сопровождением которой мы занимаемся в «Спортмастере». Таких систем много, а необходимость в их развитии, модернизации и доработке есть всегда. Почему же для демонстрации ситуации и подхода к ее разрешению взяли именно пример по модернизации МРТ? Ответ кроется в сроке эксплуатации системы и в тех архитектурных решениях, которые были заложены при ее разработке. Они позволяют рассматривать ситуацию с системой МРТ по ее модернизации как ярко выраженную, «черно-белую», почти без оттенков. Новый стек против старого, Инь и Ян. Архитектуру системы МРТ можно во многом назвать «идеальной». Говоря так, мы в первую очередь имеем в виду функциональную архитектуру с точки зрения ее использования на долгом жизненном цикле системы. При этом учитываются постоянные модернизации и доработки в рамках ее целевого предназначения. Так получилось потому, что архитектурная модель сразу разрабатывалась в предположении, что система должна будет «вбирать» в себя новые возникающие разделы товарного учета — территориальный, номенклатурный, логистический и процессный. Например, появление и вывод торговых марок и брендов с их спецификой дистрибуции. На основе нашего опыта эксплуатации систем-предшественников мы придумали и реализовали специализированные, но достаточно общие понятия и механизмы, которые в рамках описанного скоупа позволили выполнить настраиваемую декларативную модель работы с предметной областью. Это помогло решить две задачи на длинном жизненном цикле: снизить стоимость владения; снизить (а зачастую свести просто к настройкам) стоимость модернизации и доработок. Основные составляющие архитектурной модели МРТ: МРТ состоит из нескольких настраиваемых слоев:  Документы как интерфейс пользователя к операционному слою и как единица работы (создания, редактирования, удаления) пользователя. Их можно назвать «простыми», так как они построены на технологии zero-code. Операционный слой — история действий над документами, сбор необходимых атрибутов товарных запасов и приведение их в «плоский» вид для отражения проводками в учете. Переход документов по состояниям порождают операции. На диаграмме плана счетов (в нашем жаргоне — «Ромашка») тип операции соответствует стрелке перемещения товарных запасов с одного учетного регистра на другой:• План счетов МРТ («Ромашка») — модель иерархии товарных запасов и их отражения в учете;  • «Карточка ИНФО» — основной инструмент для пользователя, чтобы получить общую информацию по операциям, проводкам и товарным остаткам. Это позволяет визуализировать и проверить причины изменения данных, объяснить остаток на учетных регистрах.  Учетная Машина — слой учета:• Автоматическое отражение проводок в собственный и другие внешние учеты (сводный товарный учет, бухгалтерский). То есть отображение факта изменения учетного регистра.  «Простой» документ сразу работает консистентно по всей вертикали слоев архитектуры МРТ и даже отражается во внешнем корпоративном учете. Всё за счет настроек, ни единой строки кода — zero-code в действии. В результате мы получаем настраиваемость, обслуживаемость, малую стоимость владения, небольшую стоимость доработок.  За 10 лет эксплуатации МРТ в мире произошло многое, а в ИТ-индустрии — еще больше. Появились новые технологии, новые средства разработки и новые подходы к разработке. Не секрет, что даже самые замечательные, архитектурно продуманные системы со временем требуют реинжиниринга просто потому, что использованный технологический стек, на котором они разрабатывались и эксплуатируются, критически устарел. Критическое устаревание происходит тогда, когда технологический стек перестает поддерживаться производителем ПО. И даже не остается возможности мигрировать на новые версии ПО из технологического стека — попросту потому, что ПО перестает развиваться и поддерживаться совсем. Деградация технологического стека купируется переводом системы на новейшие версии ПО лишь частично. После достаточно длительного периода такой деградации конец всегда один: моральное и технологическое устаревание инструментов достигает такой степени, что систему становится невозможно, либо крайне дорого поддерживать, не говоря уже ее развитии и доработках. Еще один фактор устаревания — исчезновение на рынке труда специалистов, которые видят свое профессиональное развитие в работе с этими устаревшими инструментами разработки. Решающим фактором для нас стало устаревание собственного инфраструктурного фреймворка. Мы разработали его пятнадцать лет назад, когда в отрасли было мало подобных развитых инструментов. Он был необходим, но даже тогда требовал отдельной команды для поддержки и развития. В период бурного развития продуктов, построенных на нем, это было оправданно. Однако со временем развитие фреймворка прекратилось, и поддержку передали в команды разработки продуктов. Произошло это и потому, что рыночные инструменты обогнали наш: новые продукты использовали более популярные на рынке технологии, которые доросли до промышленного использования. Поэтому возможность расширить используемый технологический стек, осуществлять развитие и доработки в рамках более нового, безусловно важны для долгоживущих систем, которые не устаревают морально и не нуждаются в полном реинжиниринге из-за их функциональной пригодности для бизнеса. Визуально это отражает график жизненного цикла технологии: В момент выбора технологии реализации — это уже растущая или устоявшаяся новая технология, популярность и область применения которой увеличиваются. Поэтому со временем стоимость и риски использования падают. Но появляются другие технологии, более новые, которые вытесняю выбранную, и потому риски со стоимостью начинают возрастать, достигая критической величины. Это заставляет выбирать новые технологии исполнения, в том числе и для доработок систем, реализованных в старых технологиях. Исторически механизм распределения товара по получателям использовался в разных системах. Основной («в крупном») был в МРТ, в других системах действовали свои локальные механизмы «дораспределения» в специфичных для системы терминах, то есть более детальных аналитических разрезах. Это было нормально, пока не оказалось, что поток товара на внешних цепях должен учитываться при всех распределениях. Хорошей идеей стала централизация распределения товаров, выделение в терминах ArchiMate 3, application service. Сервис позволяет вести распределение в достаточно детальных аналитиках, разрезах или измерениях для каждого из потребителей, ведь каждый имеет собственную специфику и терминологию. Маппинг обобщенных терминов сервиса и частных специфичных терминов потребителя остается за потребителем. Так и решили. Но остался другой вопрос: должен ли общий механизм распределения быть частью МРТ, предоставляемый внешнему миру как сервис? Или же это отдельная система с самостоятельным жизненным циклом? Если отдельная система — делать ли ее на старом технологическом стеке, либо выбрать новый? Изменение модели объектов логики распределения, чтобы быть достаточно универсальной, пригодной для различных потребителей сервиса Производительность распределения Высокая готовность Возможность исправления ошибок, изменения поведения системы силами инженера по сопровождению Реализация в сжатые сроки (два месяца) Что ж, какие вводные, последствия того или иного выбора здесь имелись? Очевидно, мы находились на архитектурной развилке: избрав тот или иной путь, мы переходим к системе, которая сказывается на других архитектурных решениях. В контексте разговора о нашей проблеме вспомним определения архитектуры, предложенные еще 20 лет назад. Это дискуссия Мартина Фаулера с Ральфом Джонсоном, которые рассматривали такие формулировки архитектуры, как «проектные решения, которые вы хотели бы принять как можно раньше», «всё важное», «то, что сложно изменить».  В 2014-м наш коллега Игорь Беспальчук описывал концепцию дерева архитектурных решений. Она заключалась в том, что одни архитектурные решения зависят от других (и даже существуют только в контексте «родительских», более ранних решений), и такие зависимости можно изобразить в виде дерева. Два этих суждения породили прототип нашего замысла. Он строится на трех вопросах, которые и задают ствол дерева архитектурных решений: Конечно, можно было быстро накидать аргументов «за» и «против» по каждому из трех вопросов. Главная опасность «быстрого» подхода — что-нибудь забыть. Да и одного только ощущения, что наш стек находится в своем жизненном цикле на спаде, недостаточно. Поэтому мы поступили иначе: каждый вопрос рассматривался с позиций влияния на атрибуты качества архитектуры. Перебирая список общепринятых атрибутов качества (или хотя бы крупных категорий атрибутов), мы задавались вопросом, как это повлияет на наше решение. Ведь чеклист для стандартной, но сложной, многошаговой процедуры еще никому не помешал. (Только посмотрите на историю в больнице имени Джона Хопкинса из книги Герда Гигеренцера.) В рамках статьи ответим только на первые два вопроса. Ниже приведены атрибуты качества по ISO/IEC 25010 (ГОСТ Р ИСО/МЭК 25010-2015), в самом стандарте они называются характеристиками: Вопросы о функционале (В1: внутри МРТ или нет?) и базовых технологиях (В2: те же или новые?) влияют на потенциальные архитектурные решения. Мы собрали наши рассуждения о влиянии на атрибуты качества, записали все плюсы-минусы, риски и последствия. Ответы на В1 и В2 позже помогли нам решить, каким же станет будущее решение.  Некоторые наименования атрибутов качества (характеристик) мы перевели по-другому. Там, где нет аргументов о влиянии ответов В1, В2 на качество, стоит прочерк. Функциональная пригодность → Полнота, корректность, целесообразность В1: Существуют риски, что изменение модели распределения внутри существующего МРТ приведет к большему числу «костылей», как в модели, так и в реализации. Обоснованиями будут простота и дешевизна против корректности и развиваемости. В2: — Уровень производительности → Временные характеристики, использование ресурсов, потенциальные возможности В1: См. п. «Надежность». В2: Экспертное мнение, что технология, «старая» или «новая», существенно не повлияет на производительность. Однако бенчмаркинг не проводился. Совместимость → Сосуществование, интероперабельность В1: см. В2 ↓ В2: Старый технологический стек основан на .NET Framework, следовательно, требует Windows Server. Клиент с удовольствием сократил бы число Windows-серверов. Со временем проблема будет становиться всё острее. Портирование на .NET (Core) старого технологического стека частично проводится под требования других продуктов или проектов. Но на момент старта этого проекта степень готовности портирования старого стека недостаточная. Портирование силами команды проекта возможно по скилам команды; возможность и целесообразность по бюджету и срокам необходимо оценивать. В целом этот аспект следует считать точкой чувствительности. Технических средств для интеграции с другим ПО в случае обоих стеков предостаточно. Удобство использования → Пригодность, изучаемость, управляемость, защищенность от ошибки, эстетика, доступность с ограниченными возможностями В1: — В2: Бизнес-пользователи и сопровождение привыкли к пользовательским интерфейсам на старых технологиях. Старый тонкий клиент — такой же стандартный софт на рабочем месте, как и браузер. Сохраненные ярлыки, понятная логика работы фильтров, известные способы выгрузок таблиц в Excel и многое другое.Однако, интерфейсы на новых технологиях будут больше соответствовать современному пользовательском опыту в веб-приложениях. Надежность → Зрелость, готовность, отказоустойчивость, восстанавливаемость  В1: Из контекста следует, что требования к доступности функционала распределения выше, чем к отдельно существующей системе МРТ. Это связано с тем, что функционалом распределения будут пользоваться несколько других систем, у которых из-за бизнес-ограничений другие интервалы допустимой недоступности обслуживающих сервисов, у каждой собственные требования к актуальности данных, используемых для распределения, которые выше, чем у МРТ. Соответственно, вопрос трансформируется в повышение доступности и отказоустойчивости всего МРТ против создания отдельного высоко доступного сервиса. В2: Команда DevOps в большей степени компетентна в разработке и поддержке на Linux, чем на Windows. Использование нового стека очевидным образом может вызвать появление «детских болезней» ПО, которые скажутся на зрелости (maturity) [в стандарте ГОСТ Р — «Завершенность»]. В противовес добавим, что «детские болезни» лечатся: необходимо обратить внимание техлида и QA-лида на процессы, которые помогают предотвратить их появление и смягчить последствия. Также по поводу зрелости см. п. «Сопровождаемость → Анализируемость». Защищенность → Конфиденциальность, целостность, неподдельность, отслеживаемость, подлинность В1: — В2: — Сопровождаемость → Модульность  В1: Встраивание даже сильно обособленного компонента в существующий в МРТ все равно в целом имеет более низкую модульность за счет зависимости и (или) влияния от (на) релизный цикл МРТ. Это не стоит рассматривать как критичный фактор, но точку чувствительности. В2: —  Сопровождаемость → Переиспользование В1: Сам проект по выделению функционала распределения базируется на идее переиспользования. Техническая возможность переиспользования здесь напрямую зависит от модульности. В2: — Сопровождаемость → Анализируемость В1: — В2: Старый стек имеет развитые средства диагностики, отработанные процессы по сопровождению ПО на этом стеке. На новом стеке их только предстоит найти, адаптировать, разработать. Сопровождаемость → Модифицируемость В1: — В2: Возможность найти кадры на продукт или проект существенно зависят от привлекательности не только бизнес-задач, но и технологического стека.Все последние годы рекрутинг не успевает за потребностями производства в кадровом ресурсе. Поэтому длительно оставление продуктов на старом стеке несет с собой риски, величина которых растет со временем.Связанные с техническим «перевооружением» трудозатраты составили 15% от первоначальной оценки проекта, что не оставило бы запаса на другие риски. Сопровождаемость → Тестируемость В1: — В2: — Переносимость → Адаптируемость, устанавливаемость, взаимозаменяемость В1: — В2: Веб-приложение в большей степени переносимо на будущие версии браузеров, изменения в стандартах веб-приложений, чем старый тонкий клиент.К тому же, старый тонкий клиент завязан на .NET Framework 4.0, а значит, и Windows. В какой-нибудь новой Windows эта версия .NET Framework просто перестанет работать. Поднять же версию .NET Framework или портировать клиент на .NET 7 — отдельные ресурсозатратные задачи.См. также п. «Совместимость». Кратко резюмируя анализ выше, можно сказать, что на одной чаше весов находится устойчивость существующих решений, на другой — развиваемость системы, затраты на техническое перевооружение на первом этапе и риски «детских» болезней новых решений. Перевесила идея отдельного сервиса и нового технологического стека. Самое время сделать записи Architecture Decision Record (ADR): № 1 Код. APP-DETACHED-SERVICE Описание. Функционал распределения товара представляет собой отдельную систему (сервис). Обоснование. В паре с решением #APP-NEW-TECH-STACK дает большие перспективы развития. Следствия. Необходима подготовка инфраструктуры для хранения кода, CI/CD новой системы. № 2 Код. APP-NEW-TECH-STACK Описание. Для сервиса распределения товара будет использован современный технологический стек, как для бэкенда, так и для фронтенда. Обоснование. Позволит сделать сервис независимым от платформы, улучшить пользовательский опыт, привлечь команду DevOps, увеличить привлекательность компании как работодателя для разработчиков, на шаг приближает к отказу от старого тонкого клиента. В противовес — умеренные затраты на технологическое обновление и риски временного ухудшения пользовательского опыта, надежности, наблюдаемости, анализируемости системы. Следствия. Требуется особое внимание аналитика, техлида, QA-лида к перечисленным выше рискам. Вообще говоря, тема фиксации архитектурных решений в реестре довольна обширная: как структурировать ADR? что записывать, а что нет? как и кто будет использовать? Тема заслуживает отдельной статьи, поэтому не будем углубляться в эти вопросы.  В некоторых проектах после проектирования, но до старта реализации, мы проводим оценку архитектуры методом анализа архитектурных компромиссов (ATAM). Это часто помогает уменьшить риски, в основном в части нефункциональных требований. Архитекторы компании, наши коллеги, делали доклад после первого успешного опыта применения ATAM в компании, презентация доступна. Полагаем, что рассказ о самом методе и практике его применения может занять еще одну отдельную статью. Решение было принято в пользу сервиса вне МРТ. Мы реализовали новую отдельную систему System of Merchandise Spreading (SMS). Она разработана целиком на новом, современном технологическом стеке и обеспечивает поддержку современных требований бизнеса «Спортмастера» по распределению входящего товаропотока по владельцам товара. Десятилетняя эксплуатация показала качество архитектуры МРТ в домене Data Architecture (в терминах TOGAF). Однако, технологии в домене Application Architecture менее живучи, требуют регулярного обновления. Мы убедились, что сделали правильный выбор, отвечая на ключевые вопросы. При проектировании новой системы SMS также закладывалась большая ее настраиваемость. После сдачи проекта никаких доработок, связанных с непроработанностью в части аналитики или разработки, не было. Объем сопровождения и сейчас находится на уровне ниже, чем в других продуктах. Все запросы обрабатываются одним инженером сопровождения, в основном настройкам системы, а изменения в коде пока не понадобились. Именно сочетание низкой стоимости сопровождения, успешное решение болезненных проблем старого технологического стека МРТ и сохранение лучших черт архитектуры данных — это мы и считаем наиболее ценным результатом. А еще, этот материал — наш первый опыт полностью коллективной статьи.  Изначальный вариант статьи содержал мало технической фактуры и был признан неинтересным для читателей «Хабра». Затем группа причастных к МРТ и SMS собралась помозгоштурмить, чем же стоит поделиться с аудиторией. Кто-то не дал закопать идею статьи для «Хабра», кто-то предложил интересный архитектурный кейс, кто-то объяснил контекст, развитие событий и принятия решений, кто-то отредактировал. Команда, работавшая над статьей: Виктор Яницкий, Владислав Иофе, Алексей Теплоухов, Юрий Солдаткин, Сергей Соболев, Александр Семененко, Юлия Колотилова.