Skip to content

Архитектурные стили

Одним из видов архитектурных паттернов являются архитектурные стили: это общий способ организации взаимодействия модулей в системе. Архитектурные стили непрерывно развиваются, выбор архитектурного стиля — очень сложное архитектурное решение, оно делается одним из первых, а потом постоянно уточняется (да, смена предпочтительного архитектурного стиля, например, монолитного на какие-нибудь «сервисы», в ходе жизни системы вполне может быть, и даже не один раз). Так, в программировании корпоративных приложений можно выделить вот такие основные стили (и множество гибридных, и множество появляющихся каждый год новых вариантов):

  • Слоистые (layered, «слоёные»): все модули бьются на слои, которые формулируются в терминах разработчиков, а не терминах предметной области. Скажем, весь ввод-вывод для пользователя делается презентационным/presentation слоем, вся предметная функциональность в слое «организационной логики» (business logic), вся конвертация данных из объектного формата в реляционный в слое «постоянного хранения» (persistence), а собственно хранение данных в базе данных как отдельном слое. Обсуждается в такой архитектуре «видимость», хотя само понятие «слоя» бралось из функциональной архитектуры (мы обсуждали в разделе проектирования слоёные архитектуры, они там давались именно как функциональные, но в архитектурных стилях это обсуждалось уже как «сгруппируем реализацию функционального слоя в модули одного модульного слоя»): нельзя модулю из презентационного слоя писать прямо в базу данных, даже если это быстро! Это хоть как-то ограничивает связность, предотвращает появление «большого кома грязи»bigballofmud» как архитектурного стиля, где «всё связано со всем, пошевелить ничего нельзя». Это самая дешёвая и простая архитектура, только беда: если нужно внести какую-то новую функциональность, то потребуется вносить изменения в каждый слой. Если каждым слоем занимаются отдельные программисты (это общий закон: в модульной структуре отдельными модулями занимаются отдельные команды, играет закон Конвея и обратный манёвр Конвея), то это потребует согласования действий множества людей, что медленно (люди будут ждать друг друга, чтобы сделать изменения) и наверняка будет вносить ошибки (не смогут точно договориться, что же где надо для чего изменить). Поэтому от таких архитектур стараются отказаться при первой же возможности, но «так уж получается, что у нас архитектура именно такая»: на саму архитектуру уходит практически ноль усилий на поддержание, она очень удобна для быстрого старта разработки!
  • Конвейеры (pipeline, «трубопроводы»): все модули представляются как «обработчики» и «фильтры», выходы одних подаются на входы других. В операционных системах есть «оболочки» (shell), которые позволяют «скриптовать», то есть прописывать вот такие «конвейеры» из разных программ-утилит. Это очень мощная архитектура! Но и тут проблемы: работы конвейера плохо распараллеливаются, производительность конвейера определяется производительностью самого медленного звена и числом звеньев (скажем, если задержка на передачу данных между модулями через сеть в конвейере 300мс, то пять модулей — и вы «изниоткуда» получаете 1.5 секунд задержки), масштабируемость при этом минимальна.
  • Микроядерная/microkernel архитектура представляет собой «основной блок» (ядро, core) и многочисленные к нему плагины/plug-ins, которые делают те или иные обработки. Это уже сильный прогресс: если хочется поддержать какую-то особую функцию, то можно сделать плагин, и не трогать всей остальной системы. Разработчики плагина могут считать себя отдельными. Но масштабируемость будет определяться одним модулем: микроядром, а не плагинами, поэтому эта архитектура тоже не решает всех проблем. Скажем, в компьютере у вас ровно такая архитектура, «plug-and-play», вы можете подключить дополнительный экран, проектор, мышь, принтер, сканер и т.д. — но всё-таки основные возможности развития совокупной системы будут ограничиваться самим компьютером, подключение разной периферии к нему удобно, но не гарантирует удобства развития самого компьютера. Когда такая архитектура была предложена как основная для операционной системы Windows, её слоганом стало plug-and-play (воткни устройство и играй), но все грустно шутили про plug-and-pray (воткни устройство, и молись, что заработает). В первые несколько лет так и было, всё работало очень ненадёжно. Но сейчас всё работает надёжно, и даже сам принцип plug-and-play не воспринимается как радикальный и новый, его просто забыли, «метанойя, не помним, как оно было до появления этой микроядерной архитектуры».
  • Сервис-ориентированная архитектура (SOA, service-oriented architecture) включает множество независимых сервисов, которые сами обслуживают в себе все «слои», но обращаются к одной базе данных, чтобы синхронизировать свои операции над ней. И у неё тоже есть недостатки: одна база данных даёт сильные зависимости, особенно концепция «транзакции» в этой базе данных: если какой-то модуль «подвис», то он может «подвесить» и базу данных, система с сервис-ориентированной архитектурой в этом плане ненадёжна. Не путаем: в наших руководствах «сервисом» называют внешнее поведение какого-то сервера/службы по изменению чего-то в окружении сервера, а в программной архитектуре так будут называть и сервис, и сервер, не особо их различая (грубо говоря, путая бег и бегуна, «сервис оказывает сервис»).
  • Микросервисная (microservices) архитектура — это развитие сервис-ориентированной архитектуры, просто база данных у каждого модуля (они тут называются «микросервисы») своя. Это обеспечивает слабую связанность, но требует повышенного внимания к синхронизации работы: все трансакции нужно программировать вручную. Возникают интересные паттерны, типа «Смыв сбоя»: если где-то в середине трансакции обнаружилась ошибка, то не нужно пытаться исправить её (это очень дорого!), нужно просто выкинуть обработку кейса, сбросив тем самым сложное сочетание состояний разных микросервисов в ходе обработки кейса. Микросервисы нарезаются по принципу «один микросервис-модуль — одна пользовательская функция/метод, она же bounded context, она же workflow/кейс как работа, выполняемая человеком и компьютером». И разрабатывает микросервисы одна команда. Управление микросервисами выполняет оркестратор, специальный модуль, отвечающий за правильность назначения прикладных микросервисов на работы по обслуживанию пользовательских кейсов (как дирижёр в оркестре, отсюда название). Есть вариант и «без оркестратора», это называется хореография (как в танце, когда дирижёра нет, а все просто прилаживаются к движениям друг друга). Это всё сложно, очень сложно, в таких архитектурах много неудач: если делать микросервисы слишком мелкими, это приводит к «распределённому большому кому грязи», что много хуже (например, медленней и запутанней в плане внесения изменений) монолитного «большого кома грязи», где все связаны со всеми, но не через сеть (микросервисы связаны через компьютерную сеть). Но зато масштабирование и производительность, а также развиваемость на таких архитектурах могут достигать таких значений, которых нельзя получить в других архитектурах.

Есть и много других видов архитектур: «пространственная», «управляемая событиями».

Подробней об архитектурных стилях можно узнать в книгах «Fundamentals of Software Architecture» и «Software Architecture: The Hard Parts», которые мы уже вам рекомендовали, если вы занимаетесь разработкой программного обеспечения. Но мы настоятельно советуем читать книги и****з раздела (в том порядке, в котором мы их давали в этом разделе, приводили их обложки) и в том случае, если вы занимаетесь разработкой систем другой природы**,** а также если вы даже не выполняете роль архитектора но ведь вы наверняка будете общаться с архитекторами, поэтому должны понимать, что у них в головах. В этих книгах как раз фронтир сегодняшней архитектурной мысли, оттуда архитектурные паттерны потихоньку будут использоваться в проектах создания и развития систем самой разной природы, а не только программных систем**.**

Архитектурные стили непосредственно влияют на то, как архитектор разбивает проект на так называемые архитектурные кванты (quanta, единственное число quantum, это латынь), по-другому называемые самыми разными терминами: сборки, компоненты и т.д. Это такие наборы модулей, которые имеют общий ввод в эксплуатацию (delivery) если заменять какой-то из них на другую версию, поэтому ими занимается обычно одна команда разработчиков. Скажем, замена резистора на плате не может произойти независимо от замены платы: впаянный в плату резистор вводится в эксплуатацию только в составе целой платы, куда он намертво впаян. Так что сборкой/квантом тут будет плата, а резистор — просто модулем в составе сборки.

Одно из достоинств микросервисного архитектурного стиля (часто говорят проще: «микросервисной архитектуры») является то, что база данных микросервиса находится внутри этого микросервиса, поэтому микросервисы можно вводить-выводить из эксплуатации независимо друг от друга, так что каждый из них может иметь свою команду разработчиков, которые мало зависят друг от друга. Это позволяет (за счёт усложнения архитектуры, это большой минус, учитываемый при выборе стиля) упростить разработку функциональности. Время ввода в эксплуатацию отдельных фич (time to market — от появления идеи до момента ввода в эксплуатацию, то есть доступности для использования) при микросервисной архитектуре становится существенно меньше. Но работа архитектора для микросервисной архитектуры становится сложнее, ибо нужно как-то оркестровать работу микросервисов, налаживать для них хореографию, а ещё микросервисы будут чудовищно медленны в обработке каждого запроса (обращения микросервисов друг ко другу весьма дороги по времени, это же чаще всего передача сообщений по компьютерной сети, а не вызов программы в той же оперативной памяти). Чудес не бывает: выбирается при прохождении развилок по выбору архитектурного стиля, как и при прохождении любых других развилок не лучший вариант, а наименее плохой.

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