Reusability, т. е. повторное использование компонентов ― весьма популярный метод в разработке ПО, веб-сервисов, дизайна и т. п. Огромным преимуществом повторного использования компонентов является экономия средств и времени на разработку ПО. Почему? Если систематизировать повторное использование компонентов, то сокращаются расходы на создание и обслуживание проектов, уменьшаются сроки разработки таких систем, во многих случаях повышается качество программных продуктов. Сегодня предлагаем поговорить об этом методе относительно веб-сайтов, JavaScript и ReactJS.
Если эта тема интересна, то давайте обсудим всё под катом. К слову, статья не очень большая, в ней приводится лишь один пример для Redux, который даёт общее понимание вопроса. А в комментариях давайте обсудим ваш опыт и идеи, которые вы используете в ежедневной работе.
Преимущества повторного использования компонентов проекта
Важный момент: для того чтобы повторное использование ПО было по-настоящему эффективным, его нужно учитывать на всех этапах проектирования. Если компания или разработчик планируют работать с повторным использованием систематически, то нужен такой процесс проектирования, в ходе которого создаваемая система разрабатывалась бы на базе уже имеющихся компонентов. Соответственно, и сама база должна быть в наличии.
Вообще говоря, повторно работать можно не только с компонентами, но и с целыми приложениями, которые включаются в общую систему проекта либо без изменения других подсистем, либо же посредством разработки целых семейств приложений, которые работают на разных платформах и адаптируются к требованиям определённых заказчиков, внутренних или внешних. Также повторно использовать можно функции, программные компоненты, реализующие отдельные функции.
Стоимость (и финансовая, и ресурсная) проекта в случае повторного использования компонентов снижается, поскольку требуется разрабатывать не все элементы проекта, а лишь часть. Соответственно, нужно меньше проектировать, реализовывать, тестировать.
Теперь о веб-разработке. Для решения проблемы с повторным использованием таких компонентов, как кнопки, поля ввода и другие простые элементы интерфейсов, в сети есть море из библиотек компонентов и разных подходов. Но допустим, что надо использовать составной компонент со своим redux-состоянием, разной логикой работы, но при этом в едином визуальном интерфейсе.
Reusability, Redux и форма для клиентов банка ― наглядный пример
Представим, что в каком-то небольшом банке есть две формы на двух разных страницах.
Форма позволяет пройти процесс рассмотрения заявки клиента банка на получение кредита. В первом поле — количество денег в займе, во втором поле — срок выплаты займа клиентом. Форма позволяет выбрать сумму выплат за месяц, при нажатии на кнопку ОК она отправляет заявку на рассмотрение.
Что в этом случае может происходить в логике работы приложения?
Чекаем доступность сервисов, необходимых для работы приложения.
Подгружаем тарифы.
Подгружаем формулу расчёта.
При движении ползунков отправляем в скоринг информацию.
Цепляем рученьки для ML.
Совершаем ещё 100500 других действий.
При необходимости запускаем разные сценарии расчёта для различных городов и стран.
При отправке формы проверяем клиента по «чёрным спискам» неблагонадёжных клиентов и выполняем ряд других проверок.
Что в этом случае может происходить в логике работы приложения?
Подгрузить тарифы.
Сказать спасибо за деньги.
Всё.
В чём проблема этого примера?
По сути у нас единый интерфейс, но в каждом конкретном случае разная логика работы внутри. Это проблема, и вот несколько способов её решения.
Решение № 1. «В лоб»
Спойлер: неправильное.
Сделать компонент, накостылить if-ов на все 500 случаев вариации, на 501-м признать, что затея была не очень удачной, и вернуться в исходную позицию, потеряв драгоценное время.
Решение 2. «Не в лоб, а по лбу»
Сделать компонент высшего порядка, в котором разруливать все хитросплетения непростой судьбы компонента. Всего за 3000 строк мы добиваемся неплохих результатов. Продуктивненько.
Решение 3. «А что если…»
А что, если наш компонент ничего не будет делать, не будет вычислять и хранить всякое безобразие, а будет только витриной для действий? Давайте скажем компоненту, что он может позволить себе быть слабым и глупым и не будет ничего решать. Пусть он будет только генерировать действия! Алгоритм простой:
формируем компонент, у которого есть поля ввода и вывода и кнопка;
при дёргании первого range мы говорим странице «Меня дёрнули» иии…
при дёргании второго мы тоже говорим странице «Меня дёрнули» иии…
при клике по кнопке мы говорим странице «Кнопка нажата» иии… ну вы поняли. Снова action.
Всё, теперь у нас внутри компонента только визуал и набор redux-экшнов, которые диспатчатся при взаимодействии. Этот визуал можно упаковать в отдельный пакет. Мы назвали такой npm-пакет виджетом и поместили в приватный registry к другим чудесным пакетам.
Виджет в терминах React — простой контейнер, но с тремя большими особенностями:
есть идентификатор на случай многократного использования на странице;
есть специфичное название, чтобы иметь общую структуру и семантику условной базы в виде redux store;
есть init-экшн, на который можно повесить базовую логику при монтировании TypeScript, чтобы не забыть что-то из этого сделать.
Как заставить всё это работать на конкретной странице?
В этом нам помогут небольшие познания в области реактивного функционального программирования, а конкретно реализации подходов через Rx.js, также библиотека redux-observable от Netflix. Благодаря всему этому наше приложение становится одним большим обсервером, который бесконечно и неустанно следит за actions на странице.
В redux-observable есть сущность, которая называется epic. С её помощью мы можем бесконечно прослушивать конкретные actions от конкретных виджетов и уже ВНУТРИ конечной «коробочки», созданной для конкретной бизнес-задачи, обрабатывать сколько угодно вариаций логики, которая не пострадает от новых данных или вводных, так как обработка — это всего лишь функция, которую для каждого случая мы можем написать и запрограммировать индивидуально.
Собственно, на этом всё, пока что мы не будем говорить о масштабном повторном использовании, для этого готовим вторую статью, уже более подробную и развёрнутую. Но хотелось бы поднять обсуждение по теме ― скажите, а применяете ли вы повторное использование у себя в компании, и если да, то насколько этот метод для вас эффективен?
Комментарии (4)
strannik_k
07.07.2022 21:47+3Другими словами - разделение кода на логику и представление улучшает возможности повторного использования кода. Ничего нового, просто то же самое применимо и к компонентам. То есть можно разделить компонент на логику и функцию, которая просто получает props и не содержит ничего кроме JSX.
Нужна большая гибкость - разбиваем логику компонента на отдельные повторно используемые сущности. Еще большая - отделяем данные от логики.Масштабно подобное не применяю, т.к. для этого потребуется самому писать и поддерживать обертку над react-ом, что затратно и выглядит не привычно для других разработчиков.
Применял бы, если бы писал библиотеку компонентов, используемую другими командами, т.к. react-way не очень хорош для этого.
Druj
08.07.2022 12:32В 22-м году люди начали понимать что реакт это библиотека для создания интерфейсов а не размазывания бизнес логики
alexshy
08.07.2022 13:20Всем, кого интересует тема, рекомендую "Learning patterns" от Lydia Hallie & Addy Osmani. Правда, у них на ее [темы] раскрытие ушло 400 стр. вместо 3-4, зато хоть польза.
markelov69
Используете Redux в связке с React'ом, мда. Вот это "уровень", смешно и плакать хочется.