Многие не знают, в чем состоит разница между архитектурой и проектированием приложения. Даже сами разработчики зачастую не могут разобрать строку кода и могут спутать элементы архитектуры приложения с элементами проектирования. Будучи разработчиком, я бы хотел объяснить эти понятия , а также разницу между проектированием приложения и его архитектурой. Помимо этого, я покажу вам, почему разработчикам важно хотя бы немного разбираться в архитектуре программного обеспечения и много — в проектировании. Итак, давайте начнем.
Определение архитектуры программного обеспечения
Говоря простым языком, архитектура программного обеспечения — это процесс превращения таких характеристик программного обеспечения, как: гибкость, масштабируемость, возможность реализации, многократность использования и безопасность — в структурированное решение, которое соответствует как техническим, так и бизнес требованиям. Отсюда возникает следующий вопрос: какие характеристики программного обеспечения могут повлиять на преоктирование архитектуры программного обеспечения? Помимо технических особенностей, также существует множество параметров, которые в основном отвечают требованиям бизнеса или функциональности.
Характеристики архитектуры ПО
Как я уже объяснил, характеристики ПО помогают понять требования к программному обеспечению и ожидания, относительно его на функциональном и техническом уровне. Поэтому, если владелец продукта говорит, что им приходится конкурировать в условиях быстро меняющегося рынка , значит, им следует быстро адаптировать свою бизнес-модель. Программное обеспечение должно «легко расширять свой функционал, состоять из блоков и быть легким в обслуживании», если мы хотим, чтобы оно было подготовлено качественно и вовремя. Если вы архитектор ПО, то должны знать, что основными параметрами для вас будут качество работы и высокая отказоустойчивость, масштабируемость и надежность. А теперь, определившись со всеми основными параметрами, вы слышите от своего руководителя, что бюджет на этот проект ограничен. Здесь вступает в дело ещё один параметр — осуществимость.
Полный список параметров программного обеспечения или так называемых «качественных характеристик» вы найдете здесь.
Архитектурные шаблоны программного обеспечения
Большинство из вас, наверно, уже знакомы с термином «микросервисы». Микросервисы — один из способов моделирования архитектуры ПО, наряду с многоуровневой архитектурой, архитектурой, управляемая событиями, бессерверной архитектурой и многими другими. Некоторые из вышеперечисленных шаблонов будут описаны ниже. Микросервисный стиль архитектуры стал известным после того, как его стали успешно применять в Amazon и Netflix. А теперь, давайте углубимся в детали и более подробно обсудим архитектурные стили.
** Внимание: пожалуйста, не путайте архитектурные стили с шаблонами проектирования, такими как фабричный шаблон проектирования или адаптерами. Я расскажу о них позже.
Бессерверный архитектурный стиль
Этот элемент применим к приложениям, которые в качестве решения используют сервисы третьих лиц для того, чтобы решить проблему загруженности серверов и бэкенда. Бессерверная архитектура делится на две основные категории. Первая это «бэкенд как услуга (BaaS)», вторая — «функция как услуга (FaaS)». Бессерверная архитектура поможет сэкономить время на проверке и исправлении ошибок переноса, а также на работе с регулярными задачами сервера.
Самым известным примером бессерверного API является сервис Amazon AWS «Lambda».
Более подробно прочитать о нем вы можете здесь.
Архитектура, управляемая событиями
Эта архитектура завязана на производителях и потребителях событий. Главная идея состоит в том, чтобы разделить части вашей системы так, чтобы каждая из частей активизировалась, когда интересное событие происходит в другой. Сложно? Давайте упростим. Представьте, что вы создаете систему для онлайн-магазина и она состоит из двух частей: модуль покупок и модуль продаж. Когда клиент совершает покупку, модуль покупок создает событие «orderPending». Так как модуль продаж заинтересован в этом событии, он будет следить за процессом на случай, если его вызовут. Как только модуль продаж получит это событие, он выполнит определенные задания или запустит ещё одно событие для продолжения покупки товаров у определенного вендора.
Запомните, что производитель события не знает за каким из событий наблюдает какой из потребителей события. Также и другие потребители не знают, кто из них за каким событием наблюдает. Таким образом, главная идея заключается в расщеплении частей системы.
Если вы хотите узнать больше про архитектуры, управляемые событиями, перейдите по ссылке.
Архитектура микросервисов
За последние несколько лет архитектура микросервисов стала одной из самых популярных. Она создается на основе небольших, независимых модульных сервисов, каждый из которых решает свою проблему или выполняет уникальное задание. Эти модули взаимодействуют через API, запрограммированный на выполнение определённой бизнес цели. А теперь посмотрите на картинку и вы все поймёте.
Проектирование программного обеспечения
Архитектура — это скелет и многоуровневая инфраструктура программного обеспечения, а проектирование ПО — это проектирование на уровне кода, например: чем занят каждый из модулей, разнообразие классов, цели функций, и т.д.
Если вы разработчик, вам необходимо знать принципы SOLID, и понимать, как шаблон проектирования должен решать повседневные проблемы.
Принципы SOLID ( Single Responsibility, Open Closed, Liskov substitution, Interface Segregation and Dependency Inversion Principles) — это единственная ответственность, открытость/закрытость, принцип подстановки Барбары Лисков, принцип разделения интерфейсов и принцип инверсии зависимостей.
- Принцип единственной ответственности означает, что каждый класс работает только над одной целью, ответственен только за неё и изменяется только по одной причине.
- Принцип открытости/закрытости: класс должен быть открытым для расширения, но закрытым для изменений. Проще говоря, вы можете добавлять новую функциональность в класс, но не можете редактировать существующие функции таким образом, что они будут противоречить используемому коду
- Принцип подстановки Барбары Лисков: согласно этому принципу, разработчик должен соблюдать наследственность таким образом, чтобы нигде не нарушалась логика приложения. Так, если новый класс «XyClass» происходит от родительского класса «AbClass», новый класс должен повторять функции родительского класса таким образом, чтобы они не изменяли поведение родительского класса. Тогда вы легко сможете использовать объект XyClass класса вместо объекта класса AbClass, не нарушая логики приложения.
- Принцип разделения интерфейсов: Всё просто: класс способен реализовывать множество интерфейсов, создавайте свой код таким образом, чтобы классу никогда не приходилось реализовывать функцию, которая не важна для его задач. Вывод — разделяйте свои интерфейсы на категории.
- Принцип инверсии зависимостей: Если вы когда-либо использовали TDD для создания своего приложения, вы знаете насколько важно расщеплять свой код перед тестированием и моделированием. Другими словами, если определенный класс «ex:Purchase» зависит от класса «Users», установка пользовательских объектов должна инициировать снаружи класса «Purchase».
Шаблоны проектирования
- Фабричная модель — самый часто используемый шаблон проектирования в мире OOП, так как он позволяет сэкономить много времени в будущем, когда потребуется изменить один из классов, который вы использовали. Рассмотрим на примере:
Представим, что вы хотите реализовать модель класса пользователей Users(), — вы можете использовать один из двух методов:
1 — $users = new Users();
2 — $users = DataFactory::get(‘Users’);
Я бы выбрал второй, по двум основным причинам, помимо всех остальных. Во-первых, изменение названия класса с «Users» на «UserData» — это всего лишь одно изменение в одном месте, внутри фабричной базы, в остальном ваш код остается тем же. Во-вторых, если в классе «Users» появятся такие параметры как Users($connection), то вам останется только внести изменения в одном месте, а не в каждой функции которая использует объекты класса Users. Поэтому, если вы думаете, что первый вариант лучше, подумайте ещё раз.
- Адаптер (шаблон проектирования) — один из шаблонов структурного проектирования. Посмотрев на название, можно понять, что эта модель делает из неожидаемого использования класса ожидаемое.
Представьте,что ваше приложение работает по API c YouTube и, чтобы получить токен доступа, вам необходимо вызвать функцию getYoutubeToken();
Итак, вы вызвали эту функцию в 20 разных местах в приложении.
А потом, Google публикует новую версию API, переименовав функцию на getAccessToken();
Теперь вам придется найти и переименовать эту функцию во всем приложении или создать адаптер-класс, как показано далее в примере:
В последнем случае, единственное, что вам придется сделать — изменить одну строку, все остальное приложение продолжит работать как раньше.
Помните, что архитектор программного обеспечения и разработчик программного обеспечения — две разные вещи. Архитекторы программного обеспечения обычно работают с опытным тимлидом, который хорошо знает существующие решения, что помогает ему принимать правильные решения на стадии планирования. Разработчик программного обеспечения должен знать особенности проектирования программного обеспечения и также обладать знаниями об архитектуре приложения, чтобы команде было легче взаимодействовать.
Перевод статьи Mohamed Aladdin: Software Architecture — The Difference Between Architecture and Design