Спринт 12/18: Архитектура системы → Тема 3/6: Монолитные и распределенные стили → Урок 1/4
Многослойная архитектура
В прошлых уроках вы познакомились с фундаментальными стилями в архитектуре: клиент-серверной и серверной архитектурой. В этом уроке вы познакомитесь с самым распространённым типом монолитных стилей — многослойной архитектурой.
Даня
Когда мы с Артёмом работали в Chatty, он мне немного рассказывал о монолитной и микросервисной архитектуре. Так что я кое-что знаю 🧐
Айгуль
Отлично! Но давай более подробно разберём.
Даня
Хорошо! Наверное, сразу с микросервисной начнём?
Айгуль
Почему?
Даня
Ну, я так понимаю, монолитная — это прошлый век и сейчас её уже мало используют.
Айгуль
Это совсем не так! 🤓
Монолитная архитектура
К монолитным стилям относятся следующие типы архитектур:
Многослойная (Layered architecture) или многоуровневая.
Конвейерная (Pipeline architecture).
Микроядерная (Microkernel architecture).
Многослойная архитектура — один из самых популярных монолитных архитектурных стилей. Конвейерная и микроядерная архитектура встречается значительно реже.
Как правило, когда ПО называют монолитным, подразумевают именно многослойный тип архитектуры.
Многослойная архитектура
В многослойной архитектуре ПО, как правило, разделено на четыре элемента, которые называются слоями и выполняют уже знакомые вам функции:
Слой представления (Presentation Layer)
Выполняет логику представления.
Бизнес-слой (Business Layer)
Выполняет бизнес-логику.
Слой доступа к данным (Persistence Layer)
Выполняет логику доступа к данным.
Слой хранилища данных (Data Storage Layer)
Хранит данные.
Архитектурные слои скрывают друг от друга особенности своего внутреннего устройства и выполняют определённые функции, взаимодействуя с другими слоями.
Слой и звено
Термины «слой» (Layer) и «звено» (Tier) не следует использовать взаимозаменяемо. Слоем называют выполняющий определённую функцию элемент ПО, тогда как звено — это совокупность элементов программного и аппаратного обеспечений.
Таким образом, архитектура системы может рассматриваться как набор слоёв и как набор звеньев. Например, приложение «Контакты» на смартфоне имеет несколько слоёв, при этом оно является однозвенным, так как все функции приложения выполняются одним устройством.
Связь слоёв и звеньев
Структуры слоёв и развёртывания представляют разные точки зрения на архитектуру системы, но они связаны между собой.
Слои могут являться частью одного или нескольких звеньев. Соотнесение слоёв и звеньев определяет, например, выбранный в структуре развёртывания фундаментальный стиль.
В частности, если система имеет однозвенную архитектуру, то на единственном звене будут располагаться все слои. Если система имеет трёхзвенную архитектуру, то на клиенте будет находиться слой представления, на сервере приложений — бизнес-слой, а на сервере базы данных — слои доступа к данным и хранилища данных.
Такое представление архитектуры ПО является комбинированным, потому что описывает элементы разных структур и их связи: слои и звенья.
Закон Конвея
Многослойная архитектура является фактически стандартом большинства приложений в силу закона Конвея. Этот закон назван в честь учёного и разработчика Мелвина Эдварда Конвея (Melvin Edward Conway). Закон Конвея звучит так:
Любая организация, разрабатывающая систему, невольно будет формировать архитектуру, структура которой повторяет структуру взаимодействий внутри этой организации.
В большинстве организаций роли разработчиков разделены. Могут встречаться разработчики:
Фронтенда (Frontend) — логики представления.
Бэкенда (Backend) — бизнес-логики и логики доступа к данным.
Хранилищ данных (Data Storage) — файловых хранилищ и баз данных.
В некоторых организациях разработчиков с одинаковой ролью объединяют в отдельное подразделение. Например, в отдел разработки хранилищ. Такое разделение отлично вписывается в многослойную архитектуру, ведь каждое подразделение может заниматься реализацией отдельного слоя. Кроме того, это наиболее простой тип монолитных архитектур, соответственно, его разработка имеет наиболее низкую стоимость.
Распределите утверждения о слоях и звеньях по соответствующим категориям. Некоторые утверждения описывают и слой, и звено одновременно.
Звено
Является совокупностью программного и аппаратного обеспечения.
Является совокупностью программного и аппаратного обеспечения.
Слой
Является элементом ПО, выполняющим определённую функцию.
Является элементом ПО, выполняющим определённую функцию.
Может быть полностью реализован(о) одним разработчиком (фронтендером, бэкендером или разработчиком хранилищ).
Может быть полностью реализован(о) одним разработчиком (фронтендером, бэкендером или разработчиком хранилищ).
Оба
Скрывает особенности внутренней организации, предоставляет механизмы интерфейса для взаимодействия с ним.
Скрывает особенности внутренней организации, предоставляет механизмы интерфейса для взаимодействия с ним.
Используется для проектирования архитектурных решений, удовлетворяющих нефункциональным требованиям.
Используется для проектирования архитектурных решений, удовлетворяющих нефункциональным требованиям.
Правильных ответов: 5, неправильных ответов: 0.
Внутреннее устройство слоёв
Архитектура каждого слоя неоднородна — она состоит из множества элементов. Эти элементы представляют собой части программного кода (исходного, двоичного или исполняемого) или его эквивалентов (скриптов или командных файлов). Такие элементы называют компонентами (Components).
Компонент — это просто часть какого-то целого, поэтому под этим термином подразумевают разнородные понятия. Например, вы уже знаете, что система состоит из двух основных архитектурных компонентов: программного и аппаратного обеспечений.
Термины «элемент» и «компонент» в контексте архитектуры ПО часто употребляются взаимозаменяемо. Системный аналитик будет часто сталкиваться с разными типами компонентов в различных представлениях архитектуры, поэтому ему следует учитывать контекст использования термина — архитектурную структуру, в которой он используется.
Каждый компонент слоя в реальной системе будет расположен на каком-то элементе аппаратного обеспечения, но в структуре слоёв эта информация неважна, поэтому опускается.
Например, приложение может иметь множество серверов баз данных, на каждом из которых будет работать один или несколько компонентов. Тогда в представлении слоёв все эти компоненты будут отображены в слое хранилища данных.
Архитектор ПО может отобразить в представлении слоёв компоненты разного размера, а также показать то, как некоторые компоненты вложены в другие. Он также совместно с командой разработки может выбрать готовые компоненты, реализованные и распространяемые другими организациями, или решит реализовать их самостоятельно.
Готовый компонент предоставляет другим компонентам интерфейс, который позволяет без труда встроить его в ПО.
Существует огромное количество готовых компонентов для каждого слоя, которые отличаются друг от друга функциями, языками программирования, стоимостью и так далее.
Например, компания Camunda разработала BPMN-движок бизнес-процессов (BPMN Workflow Engine) для их автоматизации. Этот движок предоставляет возможность системным аналитикам составлять диаграммы бизнес-процессов, на основании которых будет генерироваться программный код. Таким образом, разработчикам не потребуется писать его самостоятельно.
Если архитектор ПО и команда разработки решили самостоятельно разработать компоненты, то их размер, функции и название будут уникальны. Поэтому не имеет смысла перечислять конкретные названия компонентов в уроке. Вместо этого рассмотрим разные категории компонентов, выделенные на основе выполняемых ими функций.
Компоненты слоя представления
Компоненты представления реализуют функции, необходимые для того, чтобы пользователи могли взаимодействовать с приложением. Это компоненты пользовательского интерфейса (UI), элементы управления им (UI Controls) и компоненты, обрабатывающие действия пользователя. Например:
Компоненты пользовательского интерфейса и взаимодействия
Реализуют элементы пользовательского интерфейса, автоматическое изменение их размера, разрешения, внешнего вида при отображении на разных устройствах.
Аудиовизуальные компоненты
Реализуют функции ввода/вывода речи и интеллектуального распознавания голоса, записи экрана и видео с веб-камеры.
Компоненты визуализации данных
Реализуют графики, диаграммы, карты и отчёты.
Компоненты бизнес-слоя
Бизнес-компоненты реализуют ключевые функции ПО и выражают соответствующую бизнес-логику. Это компоненты бизнес-процессов, обрабатывающих данные сущностей предметной области. Например:
Компоненты управления бизнес-процессами
Реализуют бизнес-процессы.
Алгоритмы, математические расчёты и статистика
Реализуют расчёт различных важных для пользователей показателей.
Компоненты слоя доступа к данным
Компоненты доступа к данным реализуют логику извлечения, записи, редактирования и удаления данных независимо от особенностей их хранения. Например:
Компоненты доступа к данным
Реализуют функции доступа к данным, расположенным на устройстве пользователя или на сервере базы данных.
Помощники (Helpers) и утилиты (Utility — вспомогательные программы) данных
Реализуют функции сжатия, распаковки, шифрования и дешифрования данных.
Службы данных
Реализуют функции доступа к данным, расположенным на других устройствах локальной сети или сети Интернет.
Компоненты слоя хранилища данных
Компоненты хранилища реализуют функцию хранения данных и представляют собой различные СУБД, CRM, платформы управления облачными хранилищами и другие источники данных.
Выберите слой, к которому относится функция умной колонки с голосовым помощником.
Умная колонка записывает речь пользователя.
Слой представления
За ввод звуковых сигналов (речи) отвечает аудиовизуальный компонент, входящий в слой представления.
Умная колонка распознаёт речь пользователя.
Слой представления
За распознавание голоса отвечает аудиовизуальный компонент, входящий в слой представления.
Умная колонка выполняет распознанные в речи команды пользователя.
Бизнес-слой
Команды пользователя выполняет искусственный интеллект, который относится к алгоритмам, математическим расчётам и статистике. Этот компонент расположен в бизнес-слое.
Умная колонка шифрует запись речи пользователя.
Слой доступа к данным
Функцию шифрования данных выполняют помощники и утилиты, расположенные в слое доступа к данным.
Умная колонка отправляет зашифрованную запись речи на сервер компании-разработчика голосового помощника, для усовершенствования распознавания речи.
Слой доступа к данным
Передача данных с одного устройства на другое относится к службам данных, которые расположены в слое доступа к данным.
Сервер компании-разработчика хранит запись речи.
Слой хранилища данных
За хранение данных, в том числе записей речи, отвечает слой хранилища данных. В структуре слоёв неважно, на каком устройстве расположен компонент. Компоненты распределяются по слоям, исходя из их функций, а не расположения на устройствах.
Взаимодействие слоёв
Даня
Хм, а проскочить какой-то слой можно? 🙃
Айгуль
Иногда да, а иногда нет. Всё зависит от архитектурного решения.
Даня
Это как?
Айгуль
Давай подробнее обсудим взаимодействие слоёв!
Слой — это сущность, расположенная между другими подобными сущностями или поверх них. Например, на слои разделяют атмосферу и планету Земля. Слои ПО точно так же расположены один над другим.
Запрос (Request) может последовательно проходить все слои ПО сверху вниз (от слоя представления до слоя хранилища данных), чтобы выполнить ожидаемую пользователем функцию.
После выполнения запроса формируется ответ (Respond). Ответ может проходить все слои ПО снизу вверх (от слоя хранилища данных до слоя представления), чтобы передать пользователю результат выполнения функции.
Запросом могут быть, например, просмотр остатка на счёте, снятие денежных средств с кредитной карты или оплата по кредитной карте.
Запрос на оплату формируется, когда пользователь хочет оплатить через приложение банка, например, жилищно-коммунальные услуги (ЖКУ). Запрос проходит следующий путь:
Слой представления отправляет соответствующий запрос бизнес-слою, который проверяет, может ли клиент снять указанную сумму с карты. Если денежных средств достаточно, бизнес-слой отправляет этот запрос слою доступа к данным.
Слой доступа к данным отправляет слою хранилища данных SQL-запрос, в котором указана сумма платежа.
Слой хранилища данных возвращает слою доступа к данным ответ о том, что данные о платеже успешно сохранены.
После этого слои последовательно передают друг другу этот ответ снизу вверх, а слой представления уведомляет клиента, что оплата ЖКУ прошла успешно. При этом ответ также может перемещаться между компонентами одного слоя. Ответ перемещается между компонентами разных слоёв в обратном порядке.
Запрос и ответ могут пропускать некоторые слои ПО. Обязательность прохождения через слой ПО определяется для каждого слоя по отдельности. Каждый слой может быть:
Закрытым (Closed).
Открытым (Open).
Закрытый слой
Закрытый слой означает, что запрос должен обязательно пройти через него прежде, чем перейти к следующему слою.
Если все слои закрыты, то запрос от слоя представления должен последовательно пройти через бизнес-слой и слой доступа к данным прежде, чем попасть в слой хранилища данных.
Намного проще было бы позволить запросу перейти сразу к слою хранилища данных, минуя остальные слои. При этом у такого архитектурного решения есть существенный недостаток. Если слой представления может напрямую обращаться к слою доступа к данным, то внесённые в слой доступа к данным изменения повлияют сразу на два слоя: бизнес-слой и слой представления.
Важность закрытых слоёв выражает концепция слоёв изоляции (Layers of Isolation). Если ПО реализовано в соответствии с этой концепцией, то изменения внутреннего устройства слоёв не влекут за собой необходимости изменения других слоёв.
Иными словами, изменения ограничиваются (изолируются) определённым слоем.
Например, процентные ставки за пользование денежными средствами клиентами (кредиты) и банком (депозиты) зависят от ключевой ставки центрального банка страны. Поэтому каждый раз, когда размер ключевой ставки меняется, банки оперативно изменяют ставки за пользование денежными средствами.
В соответствии с концепцией слоёв изоляции, в алгоритмы расчётов начисленных процентов по кредитам и депозитам не следует включать конкретное значение ключевой ставки. То есть в программном коде соответствующих компонентов не должно содержаться числовое значение, например 7,5%. При каждом расчёте процентной ставки актуальный размер ключевой ставки должен извлекаться из слоя хранилища данных, так слой бизнес-логики будет изолирован.
Следование концепции слоёв изоляции позволяет не только изменить, но и полностью заменить любой слой, не затрагивая остальные. Механизмы интерфейсов между слоями в любом случае должны оставаться неизменными.
Открытый слой
Иногда бывает важно, чтобы определённые слои были открытыми. Например, если в бизнес-слое есть компоненты на вторых ролях. С компонентами на первых ролях взаимодействуют компоненты других слоёв, например слоя представления, а с теми, что на вторых, — только компоненты бизнес-слоя.
Такие второстепенные компоненты, как правило, выполняют функции для множества других компонентов.
Например, компонент начисления процентов получает указания от компонентов оплаты по кредитной карте, зачисления средств и снятия наличности. При этом слою представления вряд ли понадобится давать указания компоненту начисления процентов напрямую, ведь клиенты банка не начисляют проценты самостоятельно, это всегда происходит вследствие оплаты, снятия наличных или других действий клиентов. Поэтому компонент начисления процентов является второстепенным.
Компоненты оплаты по кредитной карте, зачисления средств и снятия наличности являются первостепенными, так как они реализуют возможные действия пользователей.
Так как второстепенные «общие» компоненты расположены в бизнес-слое, компоненты слоя представления архитектурно имеют возможность обратиться к ним. А значит, разработчики должны отдельно озаботиться контролем доступа компонентов представления к общим компонентам.
Решением проблемы может стать выделение общих компонентов в отдельный сервисный слой (Service Layer). Этот слой будет выполнять указания бизнес-слоя, а у слоя представления не будет прямого доступа к второстепенным компонентам.
Добавление сервисного слоя похоже на то, как в алгебре выносят общий множитель за скобки. Например, 5х + 5y = 5*(х + y). Так же, как вынесение общего множителя за скобки позволяет упростить вычисления, вынесение общих компонентов в сервисный слой помогает упростить понимание архитектуры ПО.
Архитектор ПО может как добавить слои, так и объединить их. В частности, он может включить слой доступа к данным в бизнес-слой, потому что компоненты доступа к данным часто тесно связаны с бизнес-компонентами.
Например, для расчёта комиссии за снятие наличности компоненту бизнес-слоя необходимо знать сумму снятия и получить из компонента слоя хранилища данных актуальную процентную ставку.
Компоненты сервисного слоя реализуют общую логику, которая необходима для реализации любых ожидаемых пользователями функций. Они могут выполнять функции аутентификации, авторизации, кэширования, обработки ошибок, сбора информации об исключительных ситуациях (дата, время, тип исключения и прочее), оценки и проверки.
Сервисный слой располагается под бизнес-слоем. Он должен быть открытым, иначе бизнес-слой будет вынужден всегда проходить через него, чтобы получить доступ к слою доступа к данным.
Открытый сервисный слой позволяет бизнес-слою либо получить доступ к этому слою, либо перейти к слою ниже.
Использование открытых и закрытых слоёв помогает определить взаимосвязь слоёв и понять возможные пути прохождения запроса.
Если архитектор ПО не опишет, какие слои в архитектуре являются открытыми и закрытыми, то это приведёт к созданию тесно связанных и хрупких архитектур, которые сложно реализовывать, развёртывать, тестировать и сопровождать.
Рейтинг архитектурных характеристик
Даня
Как многослойный стиль устроен, теперь понимаю, а вот для каких приложений он подходит — нет. Для интернет-магазина можно использовать?
Айгуль
Вполне! А определиться со стилем поможет рейтинг архитектурных характеристик.
Рейтинг архитектурных характеристик включает основные критерии выбора архитектурного стиля. В него входят наиболее важные характеристики ПО, которые позволяют сделать выбор в пользу того или иного стиля.
Каждой архитектурной характеристике стиля соответствует рейтинг: низкий или высокий. Это значит, что в сравнении с другими стилями характеристика конкретного стиля проявляет себя хуже или лучше.
Производительность (низкий)
Этот стиль не подходит для приложений, требующих больших вычислительных мощностей, из-за неэффективности прохождения запросом слоёв. Так как в соответствии с изоляцией слоёв они должны быть закрытыми, запрос будет проходить через большее количество слоёв.
Возможность модификации (низкий)
Это способность быстро реагировать на постоянно изменяющуюся среду. В этом стиле изменения могут быть изолированы закрытыми слоями, но для передачи этих изменений пользователям всё равно требуется разворачивать всё приложение целиком.
Масштабируемость (низкий)
Развёртывание приложений достаточно громоздкое, что делает масштабирование дорогостоящим.
Простота разработки (высокий)
Эта архитектура хорошо известна и не слишком сложна в реализации. Большинство компаний разрабатывают приложения, разделяя слои по закону Конвея в соответствии с различными ролями разработчиков.
Простота развёртывания (низкий)
Монолитные стили подразумевают развёртывание всего программного кода ПО единовременно. Это значит, что все слои вводятся в эксплуатацию вместе. То есть невозможно, например, изменить небольшой элемент интерфейса без обновления всего ПО сразу.
Единое развёртывание больших приложений может занимать часы или даже десятки часов. Во время обновления приложение недоступно пользователям, что создаёт для них неудобства. Также это создаёт неудобства для команды разработки, так как сотрудники вынуждены развёртывать ПО по ночам и в выходные дни.
Развёртывание всех слоёв сразу влияет и на работу системного аналитика. Ему необходимо:
Помнить, что приложение можно обновить только в определённые дни и часы. Это ограничение ему нужно также доносить до заинтересованных лиц, которые, как правило, хотят увидеть изменения ПО как можно скорее.
Уделять особое внимание вертикальной декомпозиции требований, ведь команде разработки нужно в заданные сроки реализовать как можно больше функций.
Искать «обходные пути». Например, как можно изменить работу приложения без его развёртывания в случае непредвиденных ситуаций или возникших ошибок. Возможности изменения приложения без его развёртывания сильно ограничены.
Помнить, что даже изменение в работе одних функций может привести к проблемам в работе других функций. Это значит, что даже маленькое изменение создаёт необходимость тестирования всех ключевых функций приложения.
Простота тестирования (высокий)
Компоненты одного слоя можно протестировать отдельно от других слоёв с помощью реализации прототипов слоёв и их интерфейсов, что делает эту архитектуру достаточно простой для тестирования.
Разработчик фронтенда может, например, реализовать прототип слоя представления, чтобы тестировщики могли проверить работу компонентов бизнес-слоя изолированно. Или, наоборот, имитировать бизнес-слой для тестирования функций в слое представления.
Когда использовать многослойную архитектуру
Многослойная архитектура отлично подходит для:
Небольших и простых приложений
По мере роста приложения с многослойной архитектурой страдают такие его характеристики, как удобство обслуживания и эксплуатации, гибкость, тестируемость и возможность развёртывания. По этой причине этот стиль подойдёт только для небольших приложений. Например, многослойная архитектура может подойти для интернет-магазинов, но не для маркетплейсов.
Ограниченного бюджета и времени разработки
Многослойная архитектура — один из самых недорогих архитектурных стилей из-за её простоты и привычности для проектирования, реализации и тестирования.
Начала разработки приложений
В силу относительной простоты проектирования, реализации и тестирования, многослойная архитектура подходит для тех команд разработки, которые приступают к созданию приложения. В дальнейшем они могут выбрать другой стиль архитектуры и переделать приложение.
Подведём итоги
Многослойная архитектура является одним из самых популярных монолитных архитектурных стилей. ПО с многослойной архитектурой называют монолитным.
Монолитный стиль подразумевает развёртывание всего программного кода системы единовременно. Это значит, что вся система вводится в эксплуатацию в один момент времени. Системный аналитик должен учитывать это в работе.
В многослойной архитектуре ПО разделено, как правило, на четыре элемента, которые называются слоями и выполняют уже знакомые вам функции:
Слой представления (выполняет логику представления).
Бизнес-слой (выполняет бизнес-логику).
Слой доступа к данным (выполняет логику доступа к данным).
Слой хранилища данных (хранит данные).
Архитектор ПО может как добавить слои, так и объединить их.
Каждый слой может быть:
Закрытым (запрос должен пройти через такой слой прежде, чем перейти к следующему).
Открытым (запрос может пройти через такой слой прежде, чем перейти к следующему).
Важность закрытых слоёв выражает концепция слоёв изоляции. Следование концепции слоёв изоляции позволяет не только изменить, но и полностью заменить любой слой, не затрагивая остальные. Механизмы интерфейсов между слоями в любом случае должны оставаться неизменными.
Открытым слоем может быть сервисный слой, который выполняет указания бизнес-слоя с помощью общих компонентов.
Многослойная архитектура отлично подходит для:
Небольших и простых приложений.
Ограниченного бюджета и времени разработки.
Начала разработки приложений.
Draggable item. Ensure your screen reader is not in browse mode and then press space bar to lift.