технологии разработки веб приложений
Стек технологий для разработки веб-приложений: что важно знать бизнесу
Время чтения: 10 минут
Отправим вам статью на:
Один из наиболее важных шагов, которые нужно предпринять, когда дело доходит до разработки приложения, — это выбрать правильный стек технологий. Этот вопрос значительно влияет на успех проекта, как в краткосрочной, так и долгосрочной перспективе. Почему? Стек технологий для разработки веб-приложений влияет на стоимость проекта, сроки выпуска продукта на рынок, безопасность и масштабируемость приложения. Грамотно подобранный стек позволяет получить стабильный, безопасный и удобный в обслуживании продукт, который не только завоюет сердца ваших клиентов, но и позволит вам масштабировать бизнес.
Веб-приложение: что такое, из чего состоит, виды
С точки зрения архитектуры веб-приложения состоят из двух частей: клиентской и серверной. Клиентская часть также называется фронтэнд. По сути это то, что пользователи видят на экране устройства. Серверная часть, или бэкенд — программно-аппаратная часть сервиса. Это набор средств, которые реализуют логику приложения.
Взаимодействие клиентской и серверной частей веб-приложения
Клиентская часть приложения
Фронтэнд, т.е. клиент представляет собой интерактивную часть программы, которая исполняется в веб-браузере на компьютере, смартфоне или планшете. Клиентская часть реализует пользовательский интерфейс веб-приложения и загружается в виде динамических веб-страниц.
Рассмотрим основные компоненты стека интерфейсов.
Каскадные таблицы стилей (CSS) — это язык разметки, который определяет оформление и макет элементов HTML. Таким образом, HTML задаёт структуру, а CSS — стиль. С помощью CSS задаются шрифты, цвета, стили, расположение отдельных элементов, а также отображение страниц на разных устройствах.
JavaScript
JavaScript — это язык программирования, который помогает реализовывать сложное поведение веб-страницы. В большинстве случаев JavaScript используется для создания адаптивных интерактивных элементов для веб-страниц, которые улучшают взаимодействие с пользователем. С помощью JavaScript можно создавать меню, анимацию, видеоплееры, интерактивные карты и даже простые игры в браузере.
Чтобы эффективнее разрабатывать на JavaScript, разработчики используют фреймворки, которые также являются важной составляющей технологического стека. Фреймворк — это рабочая среда, своего рода каркас, который помогает эффективнее создавать и поддерживать программные продукты. Далее мы перечислим некоторые из фреймворков и библиотек, которые мы обычно используем в проектах.
Популярные фреймворки и библиотеки JavaScript
Одна из ключевых особенностей React — универсальность. Эту библиотеку можно использовать на сервере и на мобильных платформах с помощью React Native.
Ещё одна важная особенность библиотеки — декларативность. С помощью React разработчик описывает, как компоненты интерфейса выглядят в разных состояниях. Декларативный подход сокращает код и делает его понятным.
Angular — это фреймворк от компании Google. Прежде всего он нацелен на разработку SPA-решений.
Эта среда разработки известна прежде всего потому, что она предоставляет разработчикам лучшие условия для объединения JavaScript с HTML и CSS. К веб приложениям на Angular.js относятся Google и Youtube.
Vue — это прогрессивный фреймворк для создания пользовательских интерфейсов. В отличие от фреймворков-монолитов, Vue подходит для постепенного внедрения. Он легко интегрируется с другими библиотеками и существующими проектами. Также Vue пригоден, чтобы создавать сложные одностраничные приложения, если использовать его совместно с современными инструментами и дополнительными библиотеками.
Серверная часть приложения
Под серверной частью понимают набор аппаратно-программных средств, с помощью которых реализована логика работы приложения. Это то, что происходит вне браузера и компьютера пользователя. К бэкенду относится панель администрирования, управление данными, логика их передачи по запросам фронтенда.
Задача серверной разработки — сделать так, чтобы ответ от сервера доходил до клиента и спроектированные блоки функционировали нужным образом. А также создать для заказчика удобную и безопасную среду для наполнения и обновления контента на сайте.
PHP в основном применяется, чтобы «оживить» статичные HTML страницы. Почти всегда пользователи приходят на сайт за информацией, которая всё время меняется, и нужно отображать её актуальное состояние. Например, показать прогноз погоды. Если использовать только HTML, то решить такие задачи не получится. Здесь может помочь PHP: он принимает входящий запрос от веб-сервера, выполняет сценарий и возвращает результат в виде готового HTML-кода. Сервер отправляет этот результат в браузер пользователю, который, в свою очередь, отображает её пользователю. После этого пользователь видит актуальный прогноз погоды.
Для создания веб-приложений на PHP мы используем фреймворк Laravel. Его особенности: поддерживает функциональное, интеграционное и юнит-тестирование, позволяет легко масштабировать приложения, следует лучшим практикам разработки и предлагает большой выбор шаблонов проектирования. Всё это помогает поддерживать чистую, минималистичную и эффективную кодовую базу, которую легко модифицировать.
Также из PHP фреймворков применяем Yii2 и Symfony.
Для разработки веб-приложений на Java мы используем фреймворк Spring. Он обеспечивает комплексную модель разработки и конфигурации для современных бизнес-приложений: от ecommerce-проектов до крупных порталов, от образовательных платформ до правительственных ресурсов. Ключевой элемент Spring — поддержка инфраструктуры на уровне приложения, поэтому разработчики могут сосредоточиться на бизнес-логике без лишних настроек в зависимости от среды исполнения.
Также из фреймворков Java применяем Hibernate. Он упрощает разработку Java приложения для взаимодействия с базой данных.
Node.js
Node.js — кроссплатформенная среда, которая выполняет код JavaScript вне браузера. Node.js позволяет разработчикам использовать JavaScript, чтобы получить инструменты командной строки. На стороне сервера с его помощью можно запускать сценарии для обработки динамического содержимого веб-страницы, перед тем как она будет доступна в веб-браузере пользователя.
Базы данных в разработке веб-приложений
Также веб-приложению требуется место для хранения данных, и для этого используется база данных. Существует два типа баз данных: реляционные и нереляционные. Различия между ними заключаются в том, как они спроектированы, какие типы данных поддерживают, как хранят информацию.
Реляционные БД хранят структурированные данные, которые обычно представляют объекты реального мира. Например, это могут быть сведения о человеке или о содержимом корзины для товаров в магазине, сгруппированные в таблицах, формат которых задан на этапе проектирования хранилища.
Нереляционные БД устроены иначе. Например, документо-ориентированные базы хранят информацию в виде иерархических структур данных. Речь может идти об объектах с произвольным набором атрибутов. То, что в реляционной БД будет разбито на несколько взаимосвязанных таблиц, в нереляционной может храниться в виде целостной сущности.
Внутреннее устройство различных систем управления базами данных влияет на особенности работы с ними. Например, нереляционные базы лучше поддаются масштабированию.
В инфографике ниже мы собрали основные технологии разработки веб-приложений, которые мы используем.
Заключение
Подпишитесь
Оставьте адрес, и каждый месяц мы будем высылать свежую статью
о новых трендах в разработке програмного обеспечения.
Современная веб-разработка: выбери себе приключение
Привет. Недавно я делал доклад для студентов о том, какие шишки можно набить, занимаясь современной веб-разработкой. Как связаны друг с другом различные решения, которые мы принимаем в процессе разработки, как выбор технологий влияет на размер команды, как размер команды влияет на подходы к тестированию, как подходы к тестированию связаны со структурой всей компании.
Получилось что-то вроде квеста с распределенным выбором: от того, какой язык программирования выбрать и до того, кого лучше нанимать в команду, которая сделает самый полезный продукт ever. Предлагаю вам почитать этот пост, выбрать свои варианты, дополнить квест и обсудить то, что наболело.
upd — немного дополнил текст до ката.
От идеи до прототипа
Предположим, что я и мой друг Валерка решили сделать стартап. Uber for X, или там еще что-нибудь в таком духе. Собрались в баре, обсудили эту идею, клёвая тема. Надо сделать. Три месяца не спали, не ели, не выходили из дома. Разрабатывали. Запустили и поняли, что это никому не нужно.
Печаль. Попробуем еще раз. На этот раз мы изучили рынок, посмотрели, какие потребности у пользователей, какие проблемы. Мы сделали какой-то прототип совсем на коленке, быстро и бесплатно за два вечера. Прототип взлетел. Круто, идем дальше.
Выбираем технологии
Теперь мы можем брать и делать из прототипа большое приложение, развивать его. Но для этого надо более серьезно подойти к выбору технологий, которые мы будем использовать.
По порядку. На каком языке писать? Можно взять модный функциональный: Haskell, Erlang, Lisp (очень модный среди дедушек старше 70). Либо очередного убийцу JS, который очень клевый, компилируется в JS, имеет все нужные фичи. Но скорее всего, нам некого будет нанимать через год, потому что очередной убийца JS не взлетит, и придется переучиваться заново или переписывать проект.
Попытка номер два. Можно взять что-нибудь проверенное временем. Например, PHP. Это неплохой язык, его модно иногда критиковать, у него есть свои минусы, но на нем легко делать бизнес-логику, он достаточно быстрый, неплохо масштабируется, можно нанять людей когда угодно и где угодно. Но он не очень производительный. Поэтому нам нужно либо много железа, либо писать свой компилятор, как сделали Facebook или ВК.
Еще варианты? Можно взять Perl, но тогда будет некого нанимать ещё вчера. Ещё?
Java. Java — норм. Как язык не очень, на мой субъективный взгляд, но JVM — отличная виртуальная машина, все ок, быстро работает, но железа все равно нужно много. А ещё пока мы на Java писали абстрактный билдер фабрики стратегий вместо того, чтобы делать фичи, пользователи ушли к конкурентам.
Ладно, у нас есть еще Python. В принципе, у него всё ок. Но мы запускаем приложение на Python, оно использует одно ядро из 56, в остальном… все ок. Либо можно взять что-то современное: Go, Rust, еще что-то. Но они слишком низкоуровневые, и мы просто долго делаем фичи… Какой-нибудь язык нам всё равно придется выбрать. Пусть в итоге это будет JS, сойдет.
База данных
База. JS без документной базы — деньги на ветер. У документных баз есть свои плюсы. Они позволяют нам быстро разрабатывать прототипы, не париться насчет схемы, колбасить данные туда-сюда. Плюсов много, минус один: каша из данных. Когда коллекций у нас становится десять, двадцать или сорок вместо трёх, когда мы без отсутствия схем пытаемся склеить из них что-то хорошее и удобоваримое, становится это делать все сложнее. Опять долго делаем фичи.
Ок, давайте возьмем реляционную базу. MySQL, PostgreSQL, или Oracle, если денег хватит. С реляционными базами можно однажды прийти на работу и обнаружить себя в аду из транзакций и хранимок. Это не обязательно произойдёт с нашим проектом. Но если произойдет, то эти хитросплетения логики будет невозможно тестировать. А ещё если вдруг мы достигнем вертикального предела нашего большого золотого сервера, на котором мы хостим базу, потом будет довольно сложно их разделять. Долго делаем фичи.
Ладно. Базу взяли какую-нибудь, бахнули перед ней ORM, чтобы проще было с одного SQL на другой переезжать. Когда-нибудь (spoiler: никогда).
Архитектура
Какую взять архитектуру? Ребята на Хабре пишут, что микросервисы – это клёво. Олег Бунин говорит: «берите микросервисы».
Если начать с микросервисов, то с восьмидесятипроцентной вероятностью границы у них будут неправильные, потому что не до конца продумали доменную модель и плохо поняли, где надо резать, а где не надо. Плюс все берут микросервисы, деплоят их пачками по всему своему кластеру, и через месяц возникает вопрос: «а как это всё теперь тестировать?». Сервисы уже работают в продакшене, а мы их не тестируем. Используя привычные методологии (пирамида тестирования, ручные интеграционные тесты, end-to-end тесты), тестировать микросервисы сложно. Поэтому мы долго делаем фичи.
Ок, тогда давайте бахнем монолит. Это самая правильная идея для стартапа. Очень долго можно жить с отличным монолитом и не иметь проблем. Но если мы решим сильно расширить команду, то надо быть осторожнее. Монолит нормально масштабируется, пока разработчиков 20, 30, 50. Дальше скорость доставки фич падает экспоненциально, а мы теряем пользователей.
Где запускать проект?
Это всё надо где-то запускать. 2018 год, самый логичный вариант сделать это в облаке. Запустишь не в облаке — пацаны засмеют. Но, во-первых, есть федеральный закон 152, значительно ограничивающий выбор облачных провайдеров, у которых можно хоститься. Во-вторых, очень легко приватный ключ от своего аккаунта на Amazon случайно закоммитить в Github, и кто-то обязательно придёт и потратит все ваши деньги. А если этого не произойдёт, то в какой-то момент вас разорят облачные тарифы.
Можно арендовать дата-центр. Может, это не так ресурсоэффективно изначально, но в долгосрочной перспективе, вероятно, обойдётся дешевле, чем хоститься в облаке. Но тут нужны люди, которые это будут поддерживать. По моему опыту, те, кто это любят и умеют делать, не очень любят общаться со всеми остальными, поэтому они организуются в отдел. А отдел – это сепаратизм. Я имею в виду то, что внутри команды админов будет легче обмениваться опытом, но в будущем это может работать не очень хорошо. Будут вопросы с приоритезацией задач от других коллег, с синхронизацией. Другие специалисты не будут знать, что происходит внутри отдела, который поддерживает наш дата-центр.
В общем, сепаратизм нам не подходит. Логично переходим к вопросу набора команды.
Команда
Разработка
Допустим, мы разобрались с языками, базами и тем, где хостить проект. Настало время набирать команду. Можно взять несколько очень крутых ребят, которые все проблемы решат: стократные разработчики, бэкенд-ниндзи, вы понимаете. Возможно, это прокатит. Но на деле вероятно, что приглашённые звёзды будут:
В итоге… да-да, долго делаем фичи. Еще вариант — взять обычных девчонок и ребят, которые просто будут писать код, делать фичи нормально. Но если взять много не очень опытных разработчиков с разным бэкграундом, они могут писать код в разном стиле, делать штуки по-разному, и при достаточном размере команды всем будет тесно, все будут у друг друга фигурные скобочки переставлять в пуллреквестах. Это не очень эффективно. Как это можно решить? Начальник может читать весь код. Я могу читать все пуллреквесты, а мой друг и ко-фаундер Валерка потом второй раз будет перечитывать (на всякий случай, мало ли). Понятно, это не масштабируется и все медленно делают фичи.
Более правильный вариант — определить кодстайл для компании. Для многих языков он уже есть, и можно его просто соблюдать. Либо если кому-то очень хочется, можно взять готовый и подтюнить немного, и потом смотреть на пуллреквестах и говорить, что здесь фигурная скобочка не там стоит, по кодстайлу должна стоять там. С таким аргументом уже не поспоришь, но на деле это не сильно лучше предыдущего варианта, все равно мы медленно делаем фичи. Правильный вариант для всех современных языков — проверять это автоматически.
Ок. Набрали разработчиков, фигачим код. Но мы начали релизить фичи в продакшн, и нам надо как-то убеждаться, что мы без багов их катим, что у нас ничего не падает.
Quality Assurance
Можно сказать, что QA-специалисты нам не нужны. Многие так делают, это иногда работает. Но не все разработчики любят писать тесты. Их можно понять. И стоит их лучше мотивировать, чтобы тесты все-таки писали, но реальность жестока: unit-тесты ловят далеко не все баги. А если какой-то разработчик не любит писать тесты и все-таки начал их писать, то скорее всего это будут unit-тесты.
Плюс еще есть подходы, когда ты минимизируешь mean time between failures вместо mean time to recover. Mean time between failures — это когда QA специалист говорит: «не будем релизить, у меня чутье плохое, баги будут, давайте через две недели выкатим». А mean time to recover — это когда вы катите что-нибудь, сразу видите на метриках, что что-то сломалось, и через две минуты все откатили, пофиксили и все ок. Но чтобы можно было проект через две минуты откатить, надо всё покрыть нормальными метриками, а это не всегда тривиально. А если метрики в плачевном состоянии, и мы выкатим плохой релиз, мы можем узнать об этом после того, как все пользователи уйдут от нас к конкурентам.
Другой вариант: всё-таки сделать отдел QA. Вы помните: отдел — это не очень хорошо, это сепаратизм, это нам не подходит. Сепаратизм можно разрулить с помощью кроссфункциональных команд. Да, они решают проблему того, что у нас админ сидит отдельно, тестировщики отдельно.
Но создают другие проблемы. Так как разработчики, тестировщики и все прочие члены кроссфункциональных команд начинают больше общаться внутри своих команд и решать предыдущие проблемы, они меньше общаются с их коллегами по функции: другими бэкендерами и тестировщиками, они начинают переизобретать велосипеды, делать параллельно одни и те же вещи, наступает изоляция между командами. Шило на мыло: был один сепаратизм, стал другой.
Как это разрулить? Общаться с коллегами в кружках по интересам. Где-то это называют гильдиями, где-то — коммьюнити. Если мы масштабируем команду кроссфункциональными командами, чтобы они не замыкались в себе, мы просто организуем кружок любителей бэкенда, функциональных языков, секьюрити…
Итоги
На самом деле, не всё так плохо. Из любой ситуации можно найти выход, найти решение. Может быть, не идеальное, но наиболее подходящее в данной ситуации с минимумом проблем. Всегда возможен компромисс.
А ещё — всё это интересно. Интересно решать проблемы, которые уже кто-то решал, новые проблемы еще интереснее решать. Интересно делиться знаниями.
Семь принципов создания современных веб-приложений
Эта статья основана на моей презентации с конференции BrazilJS в августе 2014 года. Она базируется на идеях, о которых я писал в блоге недавно, в основном, в связи с UX и производительностью.
Я хочу представить 7 действенных принципов для веб-сайтов, которые хотят применить JavaScript для управления UI. Эти принципы являются результатом моей работы как веб-дизайнера, но также как давнего пользователя WWW.
JavaScript бесспорно стал незаменимым инструментом для разработчиков фронтенда. Сейчас сфера его применения расширяется на другие области, такие как серверы и микроконтроллеры. Этот язык программирования выбрали престижные университеты, чтобы обучать студентов основам информатики.
В то же время существует ряд вопросов относительно его роли и конкретного использования, на которые многие затрудняются ответить, в том числе авторы фреймворков и библиотек.
1. Рендеринг страниц на сервере
tl;DR: Рендеринг на сервере осуществляется не ради SEO, а для производительности. Принимайте в расчёт дополнительные запросы для получения скриптов, стилей и последующие запросы к API. В будущем, принимайте в расчёт использование метода HTTP 2.0 Push.
Прежде всего, я вынужден обратить внимание на общепринятую ошибку разделять «приложения с рендерингом на сервере» и «одностраничные приложения». Если мы хотим добиться наилучшего восприятия с точки зрения пользователя, то не должны ограничивать себя такими рамками и отказываться от одной альтернативы в пользу другой.
Причины вполне очевидны. Страницы передаются по интернету, у которого есть физические ограничения, что незабвенно проиллюстрировал Стюарт Чешир в знаменитом эссе «Это latency, дурачок»:
Расстояние между Стэнфордом и Бостоном 4320 км.
Скорость света в вакууме 300 x 10^6 м/с.
Скорость света в оптоволокне составляет примерно 66% скорости света в вакууме.
Скорость света в оптоволокне 300 x 10^6 м/c * 0,66 = 200 x 10^6 м/c.
Односторонняя задержка при передаче в Бостон 4320 км / 200 x 10^6 м/c = 21,6 мc.
Задержка при передаче туда и обратно 43,2 мc.
Пинг из Стэнфорда в Бостон в интернете современного образца около 85 мс (…)
Итак, современное оборудование интернета передаёт сигнал со скоростью 0,5 от скорости света.
Указанный результат 85 мс можно улучшить (и уже сейчас он чуть лучше), но важно понять, что существует физическое ограничение на задержку при передаче информации через интернет, как бы не увеличивалась полоса пропускания на компьютерах пользователей.
Это особенно важно в связи с ростом популярности JavaScript-приложений, которые обычно содержат только разметку
Чистая Архитектура для веб-приложений
Хочу поделиться с вами подходом который я уже много лет использую в разработке приложений, в том числе и веб-приложений. Многим разработчикам настольных, серверных и мобильных приложений этот подход хорошо знаком, т.к. является фундаментальным при построении таких приложений, однако в вебе он представлен очень скудно, хотя желающие использовать такой подход однозначно есть. Кроме того на таком подходе написан редактор VS Code.
В результате применения этого подхода вы отвяжетесь от конкретного фреймворка. Сможете легко переключать библиотеку представления внутри вашего приложения, например React, Preact, Vue, Mithril без переписывания бизнес логики, а в большинстве случаев даже вьюхи. Если у вас есть приложение на Angular 1, вы без проблем сможете перевести его на Angular 2+, React, Svelte, WebComponents или даже свою библиотеку представления. Если у вас есть приложение на Angular 2+, но нету специалистов для него, то вы без проблем сможете перевести приложение на более популярную библиотеку без переписывания бизнес логики. А в итоге вообще забыть про проблему миграции с фремворка на фреймворк. Что же это за магия такая?
Что такое Чистая Архитектура
Для того что бы понять это, лучше всего прочитать книгу Мартина Роберта «Чистая Архитектура» (Robert C.Martin «Clean Architecture»). Краткая выдержка из которого приведена в статье по ссылке.
Основные идеи заложенные в архитектуру:
Достигается такая гибкость за счет разделения приложения на слои Service, Repository, Model. Я же добавил к Чистой Архитектуре подход MVC и получил следующие слои:
Кому подойдет Чистая Архитектура
Веб разработка прошла большой путь развития, начиная от простого скриптования на jquery до разработки больших SPA приложений. И сейчас веб приложения стали настолько большими что количество бизнес логики стало сопоставимо или даже превосходить серверные, настольные и мобильные приложения.
Разработчикам которые пишут сложные и большие приложения, а также переносят бизнес логику с сервера на веб приложения для экономии на стоимости серверов, Чистая Архитектура поможет организовать код и отмасштабироваться без проблем до огромных масштабов.
В тоже время если ваша задача просто верстка и анимация лендингов, то Чистую Архитектуру просто некуда вставить. Если ваша бизнес логика находиться на бекенде и ваша задача получить данные, отобразить клиенту и обработать клик по кнопке, то вы не прочувствуете гибкости Чистой Архитектуры, но она может стать отличным плацдармом для взрывного роста приложения.
Где уже применяется?
Чистая архитектура не привязана к какому то конкретному фреймворку, платформе или языку программирования. Десятилетия ее используют для написания настольных приложений. Его эталонную реализацию можно найти во фреймворках для серверных приложений Asp.Net Core, Java Spring и NestJS. Так же она очень популярна при написании iOs и Android приложений. Но в веб разработке он предстал в крайне неудачном виде во фреймворках Angular.
Так как я сам не только Typescript, но и C# разработчик, то для примера возьму эталонную реализацию этой архитектуры для Asp.Net Core.
Вот упрощенный пример приложения:
Если вы не понимаете что в нем написано ничего страшного, дальше мы разберем его по частям каждый фрагмент.
Пример приведен для Asp.Net Core приложения, но для Java Spring, WinForms, Android, React архитектура и код будут такие же, меняется только язык и работа с вьюхой (если она есть).
Применение в веб-приложениях
Единственный фреймворк который пытался использовать Чистую архитектуру был Angular. Но получилось это просто ужасно, что в 1, что в 2+.
И причин для этого много:
Начинаем создавать приложение
Рассматривать Чистую Архитектуру будем на примере выдуманного приложения, максимально приближенного к реальному веб-приложению. Это кабинет в страховой компании, который отображает профиль пользователя, страховые случаи, предлагаемые тарифы страхования и инструменты для работы с этими данными.
В примере будет реализована лишь малая часть функционала, но по ней можно понять где и как располагать остальной функционал. Начинать создавать приложение начнем со слоя Controller, а View слой подключим в самом конце. А по ходу создания рассмотрим каждый слой детальнее.
Паттерн Controller
Controller — отвечает за взаимодействие пользователя с приложением. Это может быть клик по кнопке на веб странице, настольном приложении, мобильном приложении, или ввод команды в консоли линукса, или сетевой запрос, или любое другое IO событие приходящее в приложение.
Самый простой контроллер в чистой архитектуре выглядит следующим образом:
Его задача получить от пользователя событие и запустить бизнес процессы. В идеальном случае Controller ничего не знает про View, и тогда его можно переиспользовать между платформами, например Web, React-Native или Electron.
А теперь давайте напишем контроллер для нашего приложения. Его задача получить профиль пользователя, имеющиеся тарифы и предложить наилучший тариф пользователю:
У нас получился обычной контроллер без чистой архитектуры, если отнаследовать его от React.Component то получим рабочий компонент с логикой. Так пишут очень много разработчиков веб-приложений, но у такого подхода есть много существенных недостатков. Главный из которых невозможность переиспользования логики между компонентами. Ведь рекомендуемый тариф может выводиться не только в личном кабинете, но и на лендинге и множестве других мест для привлечения клиента к услуге.
Для того что бы иметь возможность переиспользовать логику между компонентами ее необходимо вынести в специальный слой, который называется Service.
Паттерн Service
Service — отвечает за всю бизнес логику приложения. Если Controller’у понадобилось получить, обработать, отправить какие то данные — он делает это через Service. Если нескольким контроллерам понадобилась одна и та же логика, они работают с Service. Но сам слой Service ничего не должен знать о слое Controller и View и окружении в котором он работает.
Давайте вынесем логику из контроллера в сервис и внедрим сервис в контроллер:
Теперь если нескольким контроллерам понадобиться получить профиль пользователя или тарифы, они смогу переиспользовать одну и туже логику из сервисов. В сервисах главное не забывать про SOLID принципы и что каждый сервис отвечает за свою зону ответственности. В данном случае один сервис отвечает за работу с профилем пользователя, а другой сервис за работу с тарифами.
Но что делать если источник данных поменяется, например fetch может смениться на websocket или grps или базу данных, а реальные данные понадобиться заменить тестовыми? И вообще зачем бизнес логике что то знать о источнике данных? Для решениях этих проблем существует слой Repository.
Паттерн Repository
Repository — отвечает за общение с хранилищем данных. В качестве хранилища может выступать сервер, база данных, память, localstorage, sessionstorage или любое другое хранилище. Его задача абстрагировать слой Service от конкретной реализации хранилища.
Давайте вынесем сетевые запросы из сервисов в репозитории, контроллер при этом не меняем:
Теперь достаточно один раз написать запрос к данным и любой сервис сможет переиспользовать этот запрос. Позже мы рассмотрим пример как переопределить репозиторий не трогая код сервиса и внедрить моковый репозиторий на время тестирования.
В сервисе UserProfilService может показаться что он не нужен и контроллер может напрямую обратиться к репозиторию за данными, но это не так. В любой момент в бизнес слое могут появиться или измениться требования, может потребоваться дополнительный запрос или обогатить данные. Поэтому даже когда в слое сервиса нету логики цепочка Controller — Service — Repository должна сохраняться. Это вклад в ваше завтра.
Настало время разобраться что за заданные получает репозиторий, корректные ли они вообще. За это отвечает слой Models.
Модели: DTO, Entities, ViewModels
Models — отвечает за описание структур с которыми работает приложение. Такое описание очень помогает новым разработчикам проекта понять с чем работает приложение. Кроме того его очень удобно использовать для построения баз данных или проведений валидаций данных хранящихся в модели.
Добавим в приложение модель профиля пользователя и другие модели, и сообщим остальным слоям что теперь мы работаем не с абстрактным объектом, а с вполне конкретным профилем: