В этой статье мы не дадим исчерпывающие объяснение всем видам архитектур, но вполне доступно ознакомим с видами архитектур, их общим назначением, наиболее очевидных преимуществах и недостатках.
Что такое архитектура и для чего она нужнаАрхитекту́ра или зодчество, согласно википедии, это искусство и наука строить, проектировать здания и сооружения (включая их комплексы), а также сама совокупность зданий и сооружений, создающих пространственную среду для жизни и деятельности человека.
В той же википедии есть определения того, что такое программная архитектура
Архитектура программного обеспечения (англ. software architecture) — совокупность важнейших решений об организации программной системы, включающая в себя:
- выбор структурных элементов и их интерфейсов, с помощью которых составлена система, а также их поведения в рамках сотрудничества структурных элементов;
- соединение выбранных элементов структуры и поведения во всё более крупные системы;
- архитектурный стиль, который направляет всю организацию — все элементы, их интерфейсы, их сотрудничество и их соединение.
Наиболее понятным, на мой взгляд, кажется определение, которое объединит эти два понятия:Архитектура ПО (разработка архитектуры ПО), это искусство и наука строить и проектировать программное обеспечение таким образом, чтобы оно удовлетворяло всем заявленным к нему требованиям, а также обеспечивало максимальную простоту доработки, развертывания и масштабирования приложения.
Проще говоря, если мы решили использовать
HEAD-FIRST подход (сначала думай, потом делай), то
без проработки архитектуры нам не обойтись. Да и в ситуации, когда мы сначала всё сделали, а потом начали думать – к вопросу архитектуры мы тоже придем, только теперь с большим объемом кода, который надо переписывать.
Виды архитектуры ПОПрежде чем говорить об архитектурах ПО, стоит акцентировать внимание на том, что нижеприведенные понятия применимы исключительно в рамках клиент-серверной архитектуры. Если Вы участвуете в разработке автономного приложения, которое осуществляет все вычисления на машине клиента, например, однопользовательского калькулятора, то не нужно называть его монолитом и тем более разбивать на микросервисы.
Наиболее популярное сейчас деление архитектур (по опыту собеседований и общения с коллегами), это деление на монолитную архитектуру и микросервисную. На самом деле такое деление не совсем верно, поскольку:
Во-первых, микросервисная архитектура является подтипом сервис-ориентированной архитектуры.
Во-вторых, во некоторых проектах сейчас используется бессерверная архитектура, но ее мы, в рамках этой статьи рассматривать не будем.
Итак, монолит – это иерархическая архитектура, т.е каждый слой приложения отвечает за свою часть функционала, например: работа с базой, логирование, интерфейс (простота E2E тестирования, простота развертки). Глубоко разбирать монолиты не будем. Отметим, что есть несколько видов наиболее популярных шаблонов монолита:
Model-View-Controller (MVC, «Модель-Представление-Контроллер», «Модель-Вид-Контроллер») — схема разделения данных приложения и управляющей логики на три отдельных компонента: модель, представление и контроллер — таким образом, что модификация каждого компонента может осуществляться независимо.
- Модель (Model) предоставляет данные и реагирует на команды контроллера, изменяя своё состояние.
- Представление (View) отвечает за отображение данных модели пользователю, реагируя на изменения модели.
- Контроллер (Controller) интерпретирует действия пользователя, оповещая модель о необходимости изменений.
Model-View-Presenter (MVP) — шаблон проектирования, производный от MVC, который используется в основном для построения пользовательского интерфейса.
Элемент
Presenter в данном шаблоне берёт на себя функциональность посредника (аналогично контроллеру в
MVC) и отвечает за управление событиями пользовательского интерфейса (например, использование мыши) так же, как в других шаблонах обычно отвечает представление.
Model-View-ViewModel (MVVM) — шаблон проектирования архитектуры приложения, представленный в 2005 году Джоном Госсманом (John Gossman) как модификация шаблона Presentation Model. Ориентирован на современные платформы разработки, такие как
Windows Presentation Foundation,
Silverlight от компании
Microsoft,
ZK framework.
Микросервис – симметричная архитектура. Каждый сервис имеет свою базу и отвечает именно за бизнес-функцию (независимость от стека, масштабируемость, простота модульного тестирования).
Про масштабируемость:- Монолит - масштабируется не рационально(поднимаем всё) + не всегда возможно, если монолит изначально не писался с учетом масштабируемости
- Микросервисы масштабируются рационально (увеличиваем количество экземпляров только нужных сервисов.)
Вывод: если ваше приложении не разрастется (и Вы в этом уверены), у вас маленькая команда и сильно ограниченные ресурсы - смело выбирайте монолит.
Лайфхак: никто не догадается о том, что монолит, это монолит, если не допускать людей к кодовой базе! :)
Виды интеграцийПервое, и самое важное, что нужно понять, прежде чем мы поговорим про интеграции - чтобы произвести интеграцию, нужно больше одного приложения.
Что это означает: если у Вас есть монолитное приложение (один .exe файл), и в этом приложении один метод вызывает другой через, например,
REST API, то это просто ненужное усложнение.
Интеграция, как следует из перевода, это «внедрение». Соответственно, внедрение одного приложения в другое – целесообразно, а внедрение методов приложения один в другой – совершенно бессмысленно
.
Представим, что у нас есть 2 приложения (для наглядности, пусть это будут 2 разных приложения на 2-х разных машинах), которые мы хотим между собой подружить. Начнем!Первый вопрос, которым мы зададим себе - какой вид обмена нам нужен: синхронный, либо асинхронный?
Разберём, что такое синхронное взаимодействие.Синхронные взаимодействия это те взаимодействия, в которых одна система отправляет сообщение другой и ждет подтверждения или ответа, прежде чем продолжить работу.
Приведу пример синхронного взаимодействия: вы пришли ногами в магазин, чтобы купить там хлеб. Результатом вашего посещения магазина должна стать полученная булка хлеба, без которой домой вы не уйдете. Так вот, в данной ситуации вы взаимодействуете с магазином синхронно, т.к вы пришли туда, отдали деньги кассиру и ждете от него ответ. На примере
HTTP-запросов кассир может выдать Вам следующие ответы:
- 100 – 199 (информационные) – уточняющие вопросы от кассира, по поводу того, какой именно хлеб нужен, либо кассир пошел за хлебом на склад.
- 200 – 299 (успешные) – кассир отдает Вам хлеб.
- 300 – 399 (перенаправление) – у кассира хлеба нет, но он есть в соседнем магазине, о чем он Вам и сообщает
- 400-499 (клиентские) – пожалуй, самые часто встречающиеся ошибки, например, при интернет-серфинге. Означает, что запрос составлен некорректно, или цитируя группу “Научно-технический рэп” - «не по понятиям». Означает, что, например, у кассира хлеб есть, но конкретно фиолетовый хлеб со вкусом утренней росы, который вы запросили - в ассортименте магазина отсутствует.
- 500-599 (ошибки сервера) – что-то не то с самим кассиром, например он уснул или идентифицирует себя не как кассир, а как булка хлеба, в связи с чем не хочет продавать вам своего собрата.
В данном примере мы получим какой-то результат взаимодействия с магазином и только после этого пойдем заниматься другими делами.С синхронным взаимодействием мы разобрались, теперь давайте разберемся в том, что такое асинхронное взаимодействие.Асинхронные взаимодействия - это те взаимодействия, в которых одна система отправляет сообщение другой и не ждет подтверждения или ответа, а продолжает работу.
В данной ситуации можно привести аналогию с заказом хлеба через службу доставки.
Вы позвонили в доставку и сообщили, что Вам нужен хлеб. После этого идете дальше заниматься своими делами, не ожидая доставки хлеба. Обратите внимание, что в данной ситуации я не упомянул, что вы получили подтверждение о том, что заказ принят, т.к в рамках асинхронного взаимодействия мы не ждем никакой ответ.
Важно понять, что чаще всего нам не будут попадаться чисто синхронные или чисто асинхронные взаимодействия.Итак, с тем, что такое синхронное и асинхронное взаимодействие, мы ознакомились. Следом рассмотрим, а какие виды интеграций существуют и к какому типу взаимодействия они относятся.Файловый обменДанный метод интеграции появился достаточно давно и проверен временем. Смысл метода в том, что система номер 1 передает в систему номер 2 файл в установленном формате(например csv).
Плюсы данного подхода:- Простота
- Отсутствие необходимости соединения между системами
Недостатки:- Скорость
- Ненадежность
- Отсутствие возможности получить информацию о валидности файла со стороны вызывающей системы
В связи с вышеуказанными недостатками, при файловой интеграции обычно задумываются, как получить информацию о том, что файл действительно принят и провалидирован. Для этого реализуют, например, отправку информационных сообщений в вызывающую систему любым другим не файловым каналом (например, отправка сообщений о валидации на установленный email, запись в базу, в систему логирования и т.д).
Такой метод обмена является асинхронным, т.к, как уже было сказано выше подтверждения обработки файла отправляющая система не получает.
База к базе (или общая база данных)
Данный метод интеграции предполагает, что 2 приложения используют общую базу данных.
На самом деле для реализации данного подхода не обязательно, чтобы база была общей. Например в СУБД
Oracle присутствует механизм
database links, который позволяет получать в одной базе данных данные из другой.
Плюс данного подхода:Недостаток:- Подход создает сильную связанность между системами
Такой метод обмена является асинхронным, поскольку чаще всего подход
database links работает в одном направлении и данные в системе-получателе появляются только по запросу, т.е создать, например триггер, который отправляет данные в другую базу данных при заданном событии не получится.
Удалённый вызовИдея данного метод интеграции в том, что система 1 удаленно вызывает метод системы 2, передавая туда нужные параметры. Способов, как конкретно можно реализовать данную идею довольно много. К методам удаленного вызова можно отнести, например, интеграцию через
http/https, с использованием
REST, SOAP, GRPC и т.д.
Поскольку такой вид интеграции сейчас достаточно популярен, рассмотрим его реализации более подробно:
- GRPC – opensource фреймворк для удаленного вызова процедур.
Все запросы в рамках
GRPC строго типизированные, для их описания используются proto-файлы.
Также к дополнительным плюсам
GRPC относятся возможность отмены выполняемого запроса со стороны клиента и возможность стриминга, т.е передачи данных потоком.
Стоит отдельно выделить, что прото-файлы также поддерживают комментирование, что очень удобно.
В целом proto-файлы оформляются в стиле, похожем на код, а если быть точным, то они описываются языком
Interface Definition Language (IDL), что делает возможным генерировать сервисы на основе прото-файлов.
Пример прото-файла: