Как стать автором
Обновить

Почему долгосрочное планирование не работает в UI-разработке?

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров814
Всего голосов 3: ↑3 и ↓0+3
Комментарии2

Комментарии 2

Да, идея классная, абстрагироваться от всего, и сначала писать абстракцию, а потом реализацию. Только вот примеров мало, а потому что на практике этого очень сложно достичь. Да и на самом деле повышается сложность всего проекта, порог входа. Ну и не забываем, что за абстракцию придется заплатить. Как связать изменения данных в абстракции, и уведомление реализации о том, что ей нужно обновиться? В статье нет примера, но реакту, чтобы обновиться, нужно какое-то уведомление. Тогда у абстракции должен быть механизм подписки на свои уведомления. И вот мы получили MobX, который можно потом привязать позже к любому фреймворку, если грамотно все сначала настроить/разделить.

А еще возникают ситуации, когда данные должны обрабатываться, и храниться в таких структурах данных, которые удобно скармливать UI фреймворку, чтобы повысить производительность. Например я работаю с очень старыми устройствами, и мне нужно максимально эффективно использовать память, и удобно обновлять данные, а значит моя абстракция будет течь, и наоборот, принесет больше боли чем пользы.

А еще, как часто у вас возникал сценарий, когда вы хотели пересесть на другой фреймворк? Даже если у вас все абстрактно, пересесть на другой фреймворк будет очень дорого, ведь придется потратить много ресурсов на тестирование, и переписывание части реализации. И где-то, да и придется снова костылить утечки абстракции.
Тогда не легче, просто разделить приложение, сделать из него микрофронты, и писать каждую часть на удобном себе фреймворке? Да, получим сложную доставку, сложную инициализацию, но зато каждую часть можно будет реализовать именно так, как нам удобно.

Да и в целом, в мире бэкенда давно двинулись от идей чистой/идеальной архитектуры, в сторону микросервисов. Не замечаете некую схожесть в решении этих проблем?

Спасибо за подробный комментарий!

Попробую ответить:

Абстрагирование: привлекательность идеи vs. практические трудности  

Идея «сначала абстракция, потом реализация» выглядит заманчивой с теоретической точки зрения. На практике примеров мало, поскольку реализовать такую разделённость сложно. В итоге увеличивается общая сложность проекта и повышается порог входа для новых разработчиков. За гибкость абстрагирования приходится "платить": сложнее поддерживать и синхронизировать систему.

 Под абстракцией мы здесь говорим про абстракцию от фреймворка (но под абстракциями ещё мы понимаем сторонние зависимости, такие как бэкенд запросы или стейт). Примеров действительно мало. Действительно, большая часть приложений делается с максимальной привязкой к конкретному фреймворку. У большой части проектов на Реакте и других фреймворках, которые я наблюдал за свой путь, логика плотно связывается с хуками и, например, редаксом, от которых уже потом не откажешься. И хоть мыслить в парадигме отделения от конкретики непривычно, я всё же считаю, что это довольно просто. Поддерживать как раз такой код легче. Потому что мы можем вообще забыть, что у нас есть фреймворк. У нас теперь есть только JS объект, который легко протестировать.

Механизм уведомления об изменениях данных  

Абстрактный слой, не зависящий от конкретного UI-фреймворка (например, React), должен каким-то образом оповещать реализацию об изменениях данных. UI-фреймворки требуют уведомлений для инициирования обновления интерфейса (например, в React). Для этого абстракция должна иметь встроенный механизм подписки на события, что приводит к решениям вроде MobX, позволяющим привязать абстракцию к разным фреймворкам.

Уведомления - это деталь реализации. Можно видеть на примере в статье (tic tac toe), что мы используем useState в точке входа приложения, который мы затем используем через инъекцию в mapStateToProps. Наша вью модель (пропсы) не знает, откуда пришла эта функция, они просто получают их через пропсы. По сути же эта функция и управляет уведомлениями.

Производительность и специализированные структуры данных  

В некоторых случаях требуется обработка и хранение данных в специализированных структурах для повышения производительности, особенно на старых устройствах, где критична экономия памяти. Использование слишком общей абстракции может помешать оптимальному управлению данными, приводя к "течению" абстракций, что в итоге наносит вред производительности.

Это тоже деталь. Использование абстракций не мешает оптимальному управлению данными.

Проблемы смены фреймворка и стоимость абстракции  

Даже при наличии абстракции переход на другой фреймворк оказывается дорогим: приходится тратить ресурсы на тестирование, переписывание части реализации и устранять "утечки" абстракции. Это поднимает вопрос: не проще ли изначально разделить приложение на отдельные части (микрофронты), каждая из которых реализована в наиболее подходящем фреймворке?

Микрофронты - это тоже деталь реализации. Порой она даже не имеет архитектурной значимости (архитектура это про обобщения (интерфейсы, абстракции, принципы)), всё что можно сделать с микрофронтами можно сделать и без них. Например, если мы хотим максимально изолировать компонент от приложения внутри самого приложения, то мы можем сделать это и без микрофронтов, через выявление шва, по которому будет реализовано взаимодействие. Например, какой-нибудь простой API на основе обзерверов.

Аналогия с бэкенд-разработкой — микросервисы vs. микрофронты  

В мире бэкенда наблюдается сходный сдвиг от идеальных чистых архитектур к использованию микросервисов. Возникает вопрос: не может ли аналогичный подход (микрофронты) оказаться более практичным решением по сравнению с попытками добиться полной абстракции на уровне UI?

Проблема в том, что мы как разработчики часто не можем абстрагироваться от деталей. И вот думаем, что мы нашли инструмент, который заменит нам абстракцию, но на самом деле, мы опять завязываемся на деталь реализации (микрофронты, mobx, react и так далее). Думаю, что нужно действительно больше примеров и практики, чтобы понять, в чём же здесь разница. Я как раз пытаюсь разбираться и давать такие примеры через свои статьи.

Итог

В целом это очень непростая и непопулярная тема, но я убежден, что от этой темы не убежишь. Как программисты, мы постоянно работаем с абстракциями в виде UI и данных, и игнорировать "философские" аспекты нашей профессии можно лишь до определенного момента. Рано или поздно каждый разработчик сталкивается с необходимостью переосмыслить свой подход к архитектуре, особенно когда проект растет и усложняется. Абстрагирование от деталей реализации — это не просто теоретическое упражнение, а практический инструмент, который позволяет создавать более устойчивые и адаптивные системы в долгосрочной перспективе. Очень надеюсь, что такое осознание будет наростать.

Спасибо за интерес к статье

Зарегистрируйтесь на Хабре, чтобы оставить комментарий