карта приложений в архитектуре
Как проектируют приложения: разбираемся в архитектуре
Старший iOS-разработчик из «ВКонтакте» рассказывает, почему архитектура не главное в проекте и как сделать продукт поддерживаемым и масштабируемым.
Катя Павловская для Skillbox Media
Евгений Ёлчев
Старший iOS-разработчик во «ВКонтакте». Раньше был фулстеком, бэкендером и DevOps, руководил отделом мобильной разработки, три года преподавал iOS-разработку в GeekBrains, был деканом факультета. Состоит в программном комитете конференции Podlodka iOS Crew, ведёт YouTube-канал с видеоуроками по Flutter. В Twitter пишет под ником @tygeddar.
Я люблю спорить о том, какая архитектура лучше. Может, из-за своего внутреннего перфекциониста или диплома архитектора информационных систем, а может, потому, что мне лень копаться в плохих проектах.
Спойлер: больше всего я люблю архитектуру MVC. Дальше расскажу, как она работает и почему мне не нравятся всякие MVVM, MVP и VIPER. Кстати, недавно я разобрался во Flux и её имплементации Redux и понял, что их я тоже недолюбливаю.
В основе статьи — тред автора в Twitter.
Что такое архитектура MVC
Я тогда был студентом, делал курсовые и пет-проекты. У них была сложная вёрстка и непростая структура БД, но максимально простая логика. Код получался простым, но в целом меня такой подход устраивал.
Мне не приходило в голову, что можно делать не так, как написано в документации к инструментам и в примерах на форумах. Я был счастлив и не забивал голову чепухой.
Я пробовал поменять логику в своём проекте — перенёс её из одного файла в другой, но разницы не заметил. По факту ничего и не изменилось, только код теперь лежал в другом файле.
Изучая дискуссии в интернете и рассуждая самостоятельно, я понял, что «толстая» модель мне не нравится. Пусть лучше модель остаётся базой данных, а контроллер и дальше управляет логикой.
Со временем мои проекты становились всё сложнее, а контроллеры пухлее (правда, не как UIViewController в iOS). Я пробовал с этим бороться, выносил логику в сторонние файлы, которые включал в контроллеры, но это мало что меняло: архитектура сохранялась, просто код переносился из одного файла в другой.
Почему MVC не работала в моих проектах
В 2013 году я пересел на Laravel, разобрался с автозагрузкой классов в PHP, начал разбираться с ООП и прочитал «Совершенный код» Стива Макконнелла.
Стало ясно, что не стоит складывать всё в один файл — код и классы должны организовывать структуру, а некоторые фрагменты кода лучше убрать из MVC и выделить в самостоятельные части, которые можно переиспользовать.
С этого момента я начал писать проекты по-другому. В них появились иерархии классов, которые хранили логику, а контроллер сильно похудел — он получал данные от базы, передавал их в разные пакеты, получал от них результат и отправлял на HTML-страницу.
Архитектура проектов не была идеальной, потому что не подошла бы ни для одной сложной системы. Но для моих целей она была крутой и удобной: код получался читабельный, а все элементы проекта оставались довольно независимы.
Как я делал систему управления
VDS-сервером
В сложной системе нельзя передавать все данные через один контроллер, поэтому каждый плагин отдельно реализовывал веб- и API-интерфейсы, доступ к данным и бизнес-логику, вынесенную в пакеты для переиспользования.
Получилось так: HTML ⟷ JavaScript (модели, общение с API) ⟷ API ⟷ переиспользуемые пакеты ⟷ бизнес-логика и доступ к данным. Всё это не было похоже на MVC.
Почему архитектура не главное в проекте
Когда я увидел, как это реализуют в других компаниях, то осознал несколько важных нюансов.
Архитектура не даёт преимуществ. Ни одна продвинутая архитектура не была лучше того, что я делал в самом начале. За всё время я перепробовал разные подходы и поэтому мог оценить их пользу для проекта. Но между MVC и MVP не было разницы — кроме названий классов и правил вроде тех, когда элементы вызывают друг друга.
Компании понимают архитектуру по-разному. Одни говорят, что используют MVVM, у других то же самое называется MVC. Я видел пять MVVM-систем, и все были разными. Исключение — VIPER, у которой благодаря Егору Толстому есть подробная документация и много примеров. Но даже там были отличия.
Популярная архитектура не значит лучшая. Выбирать архитектуру из-за мейнстримности бесполезно. Кто-то решает использовать MVVM, но одни и те же компоненты кладёт в разные части проекта.
Архитектура не спасёт проект. Сама по себе она не решает проблемы и не гарантирует успеха.
Что же такое MVC на самом деле
Я постоянно изучал архитектуры, читал книги и спорил с коллегами, несколько раз пересматривал идею MVC в языке Smalltalk и несколько раз менял к ней отношение.
В итоге я понял, что MVC — это не три файла, и даже не несколько классов для каждого элемента. Модель — не про данные и не про бизнес-логику, а контроллер давно не нужен, и пора использовать MV.
Приложения с бизнес-логикой и доступом к данным были и до MVC, им не хватало только пользовательского интерфейса. Главная задача MVC — связать UI со всем остальным. Единственная рекомендация от создателя — при надобности создавать для каждой View свой фасад для Model и слушать его через паттерн-наблюдатель.
View — это и есть пользовательский интерфейс, Model — остальное приложение. Задача Controller — не быть прослойкой между V и M, а всего лишь принимать информацию от пользователя.
Принцип MVC — не мешать UI с бизнес-логикой, базой данных и другими частями приложения. А как это реализовать, уже пускай думает архитектор. Это не космическая инженерия.
Важно понимать, что MVP, MVVM или VIPER не заменяют MVC, а только дополняют её. Контроллер уже не нужен, потому что за ввод данных отвечает View, это стало его неотъемлемой частью.
Получается, что MVC в Apple, MVVM и другие варианты — это MV, где контроллер убрали за ненадобностью. Из всех современных MV(x) именно MVVM больше всего похожа на каноническую MVC.
Все эти термины усложняют общение. Иногда сложно понять, о чём тебе говорят, хотя задача архитектуры в том, чтобы всё было проще и понятнее.
Как разобраться в любой архитектуре
Может показаться, что все архитектуры одинаковые, и им вообще не стоит уделять внимания. Но это не так. У меня есть несколько правил.
Главное — реализация. Глобальная архитектура не так важна, как её воплощение. Всё зависит от того, как вы называете классы, где храните элементы и как классы общаются между собой. Все из команды должны соблюдать ваш стандарт, и тогда проект будет проще поддерживать.
Model — ваша ответственность. Архитектура MVC не даёт инструкций, как правильно написать основную часть приложения. Ваша ответственность в том, чтобы не устраивать в Model кашу, где половина классов — Service, а вторая половина — Helper.
Нужно разбираться в основах. Не стоит изучать конкретную архитектуру, лучше понять, из чего она логически следует. Тут поможет история, объектно-ориентированное и функциональное программирование, паттерны, SOLID и всё остальное. Обязательно надо прочитать «Совершенный код» Стива Макконнелла.
С какого-то момента я начал теряться в проекте. У меня появилась куча сущностей с похожими названиями и похожими данными, я создал миллиард экшенов. В итоге сам запутался, что, как и с чем взаимодействует.
Redux хороша для больших проектов, ориентированных на офлайн, где одновременно происходит куча асинхронных неблокируемых событий. Там этот бойлерплейт стоит терпеть, потому что он спасёт вам жизнь. Но в обычном тонком клиенте лучше использовать стандартную MV и не париться.
Вывод: что прочитать об архитектуре
На «Хабре» есть отличные статьи об MVC — «Охота на мифический MVC. Обзор, возвращение к первоисточникам и про то, как анализировать и выводить шаблоны самому» и «Охота на мифический MVC. Построение пользовательского интерфейса». Обязательно прочитайте их, если интересуетесь архитектурой — автор тщательно и на хороших примерах разобрал, что это такое.
Документирование архитектуры программного обеспечения
Maxim Grechushnikov (Maxyc Webber)
Mar 12, 2020 · 13 min read
Мы учимся программировать и создаем классные приложения. Затем мы узнаем об архитектуре и о том, как сделать приложение поддерживаемым в течение нескольких лет…
Однако, когда нам нужно объяснить кому-то (новому разработчику, владельцу продукта, инвестору,…), как работает приложение, нам нужно нечто большее… нам нужна документация.
В этом посте я собираюсь написать о:
Есть несколько диаграмм, которые мы можем создать с помощью UML, и мы можем разделить их на две категории:
Структурная диаграмма UML
Я не б у ду вдаваться в подробности каждого типа диаграмм, потому что это будет слишком много для освещения в этом посте. К каждому типу диаграммы я привел ссылку для ознакомления.
В целом, UML — это хороший вариант для быстрого прототипирования идей и обсуждения их с коллегами.
Однако для документирования всей архитектуры приложения с использованием UML нам необходимо будет использовать несколько типов диаграмм. Кроме того, если мы пытаемся использовать одну единственную диаграмму классов для отображения всего приложения, у нас ничего не получится.
Примером правильного использования диаграммы классов UML является документирование шаблонов проектирования:
Выглядит замечательно! Он может выражать классы, интерфейсы, юзабилити и отношения наследования, данные и поведение. Он также лаконичен и удобен для чтения, а также потому, что он маленький, его также можно быстро нарисовать.
Однако приведенный ниже пример не очень полезен … Он очень большой, поэтому становится запутанным и трудным для понимания. Более того, на его создание уйдет так много времени, что когда мы закончим, он, вероятно, уже устареет, потому что кто-то в это время внес изменения в код.
Таким образом, мы можем и должны использовать UML, но он подходит только для конкретных ситуаций: для подробного описания шаблонов, небольших частей приложения или представлений приложения на довольно высоком уровне.
Модель представления архитектуры “4 + 1”
Модель представления архитектуры 4+1 была создана Филиппом Крухтеном и опубликована в 1995 г. в его статье « Architectural Blueprints — The “4+1” View Model of Software Architecture».
Этот способ визуализации архитектуры программного приложения основан на 5 представлениях / ракурсах приложения, сообщающих нам, какие диаграммы можно использовать для документирования каждого из этих представлений.
Важно отметить, что “4+1″ не требует, чтобы мы использовали все упомянутые диаграммы и даже не все типы диаграмм. Мы всегда должны выбирать инструменты по задаче, а не наоборот.
Отчеты о решениях по архитектуре
Для начала, есть несколько моментов, которые нам нужно знать:
Я видел несколько шаблонов для создания ADR. На основе этого опыта я создал свой собственный шаблон. Вы можете создать свой, который имеет смысл в вашем проекте и команде.
Для меня самое важное для шаблона — это простота. В нем есть некоторая документация, чтобы помочь заполнить его и даже помочь принять прагматичные и объективные решения.
Лучший способ использовать ADR — это не просто документ, написанный после обсуждения и принятия решения. Лучше всего использовать его в качестве отправной точки для обсуждения, в качестве RFC (Request For Comments), который представляет собой идею / предложение, которое мы представляем другим членам команды / отдела, запрашивая их мнение / одобрение. Намерение действительно состоит в том, чтобы использовать его, чтобы начать обсуждение, провести мозговой штурм, принять наилучшее возможное решение и использовать сам документ предложения в качестве записи в журнале решений (ADR). Тот факт, что ADR написан заранее, не означает, что он является неизменным, его необходимо обновлять / улучшать по мере развития обсуждения. Я считаю особенно важным, чтобы все рассматриваемые варианты были записаны с указанием их плюсов и минусов, чтобы спровоцировать дискуссию и принять четкое решение.
Итак, вот шаблон, который я придумал:
Если вы хотите больше изучить эту тему, я рекомендую вам посетить репозиторий Джоэл Паркер Хендерсон, посвященный ADR.
Модель C4
Модель C4 была представлена Саймоном Брауном, и это лучшая идея в документации по архитектуре программного обеспечения, с которой я когда-либо сталкивался. Я быстро объясню основную идею своими словами, хотя использую собственные примеры диаграмм.
Идея состоит в том, чтобы использовать 4 различных уровня гранулярности (или масштабирования) для документирования архитектуры программного обеспечения:
Уровень 1: Диаграмма контекста системы
Уровень 2: Контейнерная диаграмма
Уровень 3: Диаграмма компонентов
Уровень 4: Код
Я думаю, что модель C4 — это отличный способ документировать архитектуру приложений, здорово понять архитектуру до определенного уровня, но я все еще нахожу ее недостаточной, хотя мне потребовалось некоторое время, чтобы разобраться в том, чего не хватает.
На этих диаграммах я вижу три ограничения:
Я нашел две категории диаграмм, которые могут помочь нам в этом.
Диаграммы зависимостей
Диаграммы зависимостей полезны для того, чтобы рассказать нам о зависимостях, которые существуют в различных типах кода в нашем коде.
Здесь крайне важно, чтобы эти диаграммы автоматически генерировались непосредственно из кода, в противном случае диаграмма будет отражать только то, как мы думаем, как выглядит код, и если бы это было точно, нам бы не понадобилась документация этого типа.
Кроме того, возможно, более важным, чем сами диаграммы, является возможность использовать анализ этих зависимостей, чтобы остановить сборку в случае нарушения наших предопределенных правил зависимостей. Таким образом, инструмент, используемый для генерации этих диаграмм, должен также использоваться в качестве инструмента тестирования и включаться в наш конвейер CI, как и модульные тесты, предотвращая нежелательные зависимости для производства, что поддерживает и обеспечивает модульность, что, в свою очередь, помогает достичь высокой изменчивости скорость и, следовательно, высокая скорость развития функции.
В этой категории диаграмм я считаю полезным иметь три разных типа диаграмм, чтобы утверждать о разных типах зависимостей.
Заметьте, однако, что я сам добавил цвета, чтобы их было легче читать в этом посте. Цвета представляют разные слои в приложении в соответствии со слоями, о которых я писал в предыдущих постах блога:
Краткий обзор 10 популярных архитектурных шаблонов приложений
Jul 29, 2018 · 7 min read
Вы когда-нибудь задавались вопросом о том, как именно разрабатываются масштабные системы крупных предприятий? До того, как перейти к непосредственной разработке программного обеспечения, мы определяемся с правильным архитектурным шаблоном, который даст нам желаемое качество и функционал. Следовательно, мы должны разбираться в нюансах различных архитектур еще до того, как применить их к своему дизайну.
Что такое архитектурный шаблон?
По материалам Википедии,
Архитектурный шаблон — это общее и повторяющееся решение часто возникающей проблемы архитектуры приложений в пределах заданного контекста. Архитектурные шаблоны схожи с шаблонами программного дизайна, однако имеют более широкий охват.
В данной статье я вкратце разберу 10 самых популярных архитектурных шаблонов, расскажу про их назначение, плюсы и минусы использования.
1. Многоуровневый шаблон
2. Клиент-серверный шаблон
4. Каналы и фильтры
5. Шаблон посредника
6. Одноранговый шаблон
1. Многоуровневый шаблон
Данный шаблон используется для структурирования программ, которые можно разложить на группы неких подзадач, находящихся на определенных уровнях абстракции. Каждый слой предоставляет службы для следующего, более высокого слоя.
Чаще всего в общих информационных системах встречаются следующие 4 слоя:
· Слой представления (также известен как слой пользовательского интерфейса)
· Слой приложения (также известен как слой сервиса)
· Слой бизнес-логики (также известен как уровень предметной области)
· Слой доступа к данным (также известен как уровень хранения данных)
Использование
· Общие десктопные приложения.
2. Клиент-серверный шаблон
Данный шаблон состоит из двух частей: сервера и множества клиентов. Серверный компонент предоставляет службы клиентским компонентам. Клиенты запрашивают услуги у сервера, а он, в свою очередь, оказывает эти самые услуги клиентам. Более того, сервер продолжает «подслушивать» клиентские запросы.
Использование
· Онлайн приложения (электронная почта, совместный доступ к документам, банковские услуги).
3. Ведущий-ведомый
В этом шаблоне также задействованы два участника — ведущий и ведомые. Ведущий компонент распределяет задачи среди идентичных ведомых компонентов и вычисляет итоговый результат на основании результатов, полученных от своих «подчиненных».
Использование
· В репликации баз данных. Там главная БД считается авторитетным источником, а подчиненные базы с ней синхронизируются.
· Периферийные устройства, подключенные к шине в компьютере (ведущие и ведомые устройства).
4. Каналы и фильтры
Этот шаблон подходит для систем, которые производят и обрабатывают потоки данных. Каждый этап обработки происходит внутри некоего компонента фильтра. Данные для обработки передаются через каналы. Эти каналы можно использовать для буферизации или синхронизации данных.
Использование
· Компиляторы. Последовательные фильтры выполняют лексический, синтаксический, семантический анализ и создание кода.
· Рабочие процессы в биоинформатике.
5. Шаблон посредника
Данный шаблон нужен для структуризации распределенных систем с несвязными компонентами. Эти компоненты могут взаимодействовать друг с другом через удаленный вызов службы. Компонент посредник отвечает за координацию взаимодействия компонентов.
Сервер размещает свои возможности (службы и характеристики) у посредника (брокера). Клиент запрашивает услугу у брокера. Затем брокер перенаправляет клиента к подходящей службе из своего реестра.
Использование
6. Одноранговый шаблон
В данном шаблоне существуют отдельные компоненты, так называемые пиры. Пиры могут выступать в роли как клиента, запрашивающего услуги от других равноправных участников (пиров), так и сервера, предоставляющего услуги другим пирам. Пир может быть клиентом или сервером, или всем сразу, а также способен со временем динамически изменять свою роль.
Использование
· Проприетарные мультимедийные приложения (как тот же Spotify).
7. Шина событий
Этот шаблон, в основном, взаимодействует с событиями и состоит из 4 главных компонентов: источник события, прослушиватель события, канал и шина событий. Источники размещают сообщения для определенных каналов на шине событий. Прослушиватели подписываются на определенные каналы. Прослушиватели получают уведомления о появлении сообщений, размещенных на каналах из их подписки.
Использование
· Разработки на Android
8. Модель-представление-контроллер
Этот шаблон также известен как MVC-шаблон. Он разделяет интерактивные прикладные программы на 3 части:
1. модель — содержит ключевые данные и функционал;
2. представление — показывает информацию пользователю (можно задавать более одного представления);
3. контроллер — занимается обработкой данных от пользователя.
Это делается с целью разграничения внутреннего представления информации от способов ее представления и принятия от пользователя. Данная схема изолирует компоненты и позволяет эффективно реализовать повторное использование кода.
Использование
· Архитектура WWW-приложений, написанных на основных языках программирования.
9. Доска
Такой шаблон подходит для проблем, для которых отсутствуют четкие детерминированные решения. Шаблон «Доска» состоит из 3 главных компонентов:
· доска — это структурированная глобальная память, содержащая объекты из пространства возможных решений;
· источник знания — специализированные модули со своим собственным представлением;
· компоненты управления — выбирает, настраивает и исполняет модули.
Все компоненты имеют доступ к доске. Компоненты могут производить новые объекты данных, которые добавляются к доске. Компоненты ищут на доске конкретные виды данных. Одним из способов поиска является сопоставление шаблонов с существующим источником знаний.
Использование
· идентификация и отслеживание транспортных средств;
· определение структур белка;
· интерпретация сигналов Sonar.
10. Интерпретатор
Он подходит для разработки компонента, который должен интерпретировать программы, написанные на специальном языке программирования. В основном, там расписано, как вычислять строки (иначе говоря: «предложения» или «выражения»), написанные на каком-то определенном языке программирования. Суть в том, чтобы присвоить класс каждому символу языка.
Использование
· языки запросов к базе данных (SQL);
· языки, которые используются для описания протоколов передачи данных.
Сравнение архитектурных шаблонов
Ниже приводятся плюсы и минусы каждого из архитектурных шаблонов.
Многоуровневый шаблон
Клиент-серверный шаблон
Шаблон «Ведущий-ведомый»
Шаблон «Каналы и фильтры»
Шаблон «Посредник»
Одноранговый шаблон
Шаблон «Шина событий»
Шаблон «Модель-представление-контроллер»
Шаблон «Доска»
Шаблон «Интерпретатор»
4 типа архитектуры программного обеспечения
Детальный обзор существующих подходов
Зачем нужна архитектура ПО
Первые разработчики создавали программное обеспечение без архитектуры. Сначала это казалось удобным: никаких издержек, связанных с планированием, и ускоренное прототипирование. Но мере усложнения ПО теряло гибкость и управляемость, а каждое новое изменение обходилось все дороже. Это мешало развивать проект за границы, определенные изначально. Такая система получила название Большой комок грязи (Big Ball of Mud).
За годы развития ПО разработчикам удалось придумать надежные подходы, чтобы устранить недостатки проектирования без архитектуры. Ниже представлены некоторые из самых известных.
Подробно рассмотрим каждую из них.
Многослойная архитектура
Этот подход работает п о принципу разделения ответственностей. ПО разделено на слои, лежащие друг на друге, и каждый из них выполняет определенную обязанность.
Архитектура делит ПО на следующие слои.
Данные и элементы управления проходят через каждый слой в дизайне и передаются от одного к другому. Эта система также повышает уровень абстракции и в некоторой степени даже стабильность ПО.
Преимущества
Недостатки
Многоуровневая архитектура
Этот архитектурный подход разделяет комплекс ПО на уровни по принципу взаимодействия “клиент-сервер”. Архитектура может иметь один, два и больше уровней, разделяющих ответственности между поставщиком данных и потребителем.
Этот подход использует шаблон Request Response для связи между уровнями. В отличие от многослойной архитектуры, он предлагает масштабируемость, которая может быть как горизонтальной (масштабирование сети с помощью высокопроизводительных узлов), так и вертикальной (масштабирование каждого узла путем повышения его производительности).
Одноуровневая система
В данном подходе единая система работает как на стороне сервера, так и клиента. Это обеспечивает простоту развертывания и отличную скорость связи, а также устраняет необходимость межсистемного взаимодействия (Inter-system communication — ISC).
Такая система подходит только для небольших однопользовательских приложений.
Двухуровневая система
Эта система состоит из двух физических машин в качестве сервера и клиента. Она обеспечивает изоляцию операций управления данными, обработки данных и операций представления.
Трехуровневая и n-уровневая системы
Такие архитектуры обладают высокой масштабируемостью как по горизонтали, так и по вертикали. Реализация n-уровневой системы, как правило, обходится дороже, но обеспечивает высокую производительность. Поэтому она обычно применяется в крупных и комплексных программных решениях.
Этот подход можно сочетать с современной сервис-ориентированной архитектурой, чтобы создавать сложнейшие модели. Поскольку реализация может оказаться дорогостоящей с точки зрения времени и ресурсов, рекомендуется использовать его для сложных ПО, требующих производительности и масштабируемости.
Сервис-ориентированная архитектура (SOA)
Эта архитектурная модель состоит из компонентов и приложений, которые связываются друг с другом с помощью четко определенных сервисов.
Она состоит из 5 элементов:
Клиент отправляет запрос с использованием стандартного протокола и формата данных по сети. Этот запрос обрабатывается ESB (enterprise service bus — сервисная шина предприятия), которая считается сердцем сервис-ориентированной архитектуры и отвечает за оркестровку и маршрутизацию. С помощью сервисного репозитория ESB направляет запрос в специальный сервис, который может взаимодействовать с другими сервисами и базами данных, чтобы составить полезную нагрузку (данные) ответа.
Полный вызов ответа на запрос согласуется с правилами управления и безопасности SOA для выполнения безопасной и корректной транзакции.
Как правило, сервисы делятся на два вида.
Типы сервисов
Mикросервисная архитектура
При таком подходе приложение разрабатывается как набор небольших сервисов, каждый из которых работает в собственном процессе и связывается с легковесными механизмами, обычно API для HTTP-ресурса.
Архитектура работает по принципу компонентизации сервисов. Она разделяет программное обеспечение на различные изолированные компоненты (сервисы), каждый из которых несет единую ответственность. Изменения в одной сервисе не должны затрагивать другие.
Состав микросервисов
Архитектура состоит из изолированных компактных микросервисов, способных расширяться независимо друг от друга. Она включает 5 следующих компонентов:
Характеристики микросервисов
Микросервисная архитектура должна включать следующие характеристики.
Рекомендуется развивать каждый микросервис отдельно под управлением разных команд. Поскольку передача данных происходит по стандартному протоколу и формату данных, структура одного сервиса не затронет функциональность сопутствующих.