[Из песочницы] Not a Flux
Расскажу об еще одной интерпретации Flux, а точнее о новом подходе в разработке интерфейсов — Not a Flux. Предполагается, что читатель хотя бы прочитал документацию о Flux.
Сначала о Flux
Что собой представляет Flux? Вкратце: это даже не паттерн, это больше способ организации архитектуры приложения. Состоит из store, dispatcher, view. Особенностью Flux является однонаправленная связь между компонентами системы посредством actions.
Взглянем подробнее на FLUX со стороны react и MVC.
Согласно философии react, выделяют controller view и view.
Controller view это родитель для других view, который отвечает за логику отрисовки его детей, получает данные из модели и отдает их детям в props. При этом инженеры Facebook говорят, что во Flux отсутствует controller. Эммм… тогда кто же рисует view, кто определяет какой view необходимо отобразить? Случаем это делает не Controller view?
В модели MVC — это контроллер, который общается с моделью, получает от нее данные и рисует view. Иными словами, контроллер это прослойка, которая работает с данными из модели, передает их во вью и отрисовывает конкретные view, в конкретный момент времени в зависимости от внешних условий. Что соответствует также философии разделения на компоненты. Не будем говорить о тех тупых контроллерах, которые делают всю работу или о тех тупых вью, которые еще и знают о модели.
Stateless View или просто VIew, что же это такое? В новом react появилась возможность создавать их еще проще, объявляя в модуле обычную функцию, которая возвращает шаблон jsx, т.е. в модели mvc это V (view). Называются они stateless functional components.
В свою очередь во вью приходит модель данных в props, с которыми эта View работает, своего рода View Model, т.е. специально подготовленные данные, которые нужны для конкретной View.
С данными Flux работает через центральное хранилище, называемое Store. В свою очередь это и есть M (Model) в MVC паттерне. Отличие состоит в том, что модель знает о dispatcher, но об этом чуть позже и одновременно Store — является центральным хранилищем для всего и вся, а также содержит некий state приложения. А также, инженеры Facebook, говорят, что Store содержит логику, но какую?
Таким образом функцию контроллера в MVC размазали между controller view и Store. Кто работал с Backbone или с другими фреймфорками, скорее всего сталкивался с проблемой необходимости хранения состояния приложения. Решить данную проблему можно разными путями, но в большинстве случаев за это отвечал либо главный контроллер, либо urls, либо localStorage.
Каким же образом children view, может сигнализировать родителю, о происходящих в нем изменениях и действиях, которые совершает пользователь? Реализовать сигнализирование можно двумя способами:
- через callbacks, передавая их через props и обзывая событиями, например, onChange. Данная стратегия, хорошо подходит для разработки отдельных переиспользуемых компонентов интерфейса: кнопок, селектов, автокомплитов и тд.
- используя паттер Mediator посредством events, которые в реакте назвали actions. Да, именно mediator в паттерне pub-sub выполняет роль некой трубы, куда сыпятся куча ивентов, а слушатели могут подписываться на нужные ивенты и работать с ними. В FLUX это называется Dispatcher.
Об Actions
Action согласно философии react состоит из названия этого действия и самих данных, что в свою очередь напоминает обычный объект event в pub-sub.
Теперь к практике
Рассмотрим обычный пример TODO на сайте Flux. Там отчетливо видно, что выделяется контроллер, который координирует все действия происходящие в диспетчере, в нужный момент лезет в store (модель), точнее подписывается на события, получает от нее данные, опять же через события pub-sub и кидает их нужным потомкам через props. Единственное, что не понятно, так это зачем обычной кнопке знать о Dispatcher и сигнализировать о своих действиях? Как потом можно переиспользовать эту кнопку в других View? Куда гибче, было бы использовать callback, а уже в parent View кидать, что-то в Dispatcher.
Так что же такое Flux? Flux — это не что иное, как комбинация структурного паттерна организации кода MVC/MVVM и паттерна взаимодействия Mediator. То, что это связь однонаправленная это и так ясно, зачем потомкам контроллера знать о модели, иначе их нельзя будет переиспользовать в других местах.
Пример из жизни
В следующей статье расскажу о применении Not a Flux способа в реальном проекте на react.
P.S.
Предлагаю всем, кто считает Flux новшеством и ищет в интернетах различные статьи о Flux, наподобие, Flux for stupids, использовать совершенно новый паттерн Not a Flux, состоящего из двух компонентов: Brain и Design patterns.
Какой из этого можно сделать вывод? На мой взгляд, надо изучать не flux и как его успешно применять в приложениях на react, а изучать основные паттерны, которые являются основополагающими в разработке ПО, например, структурные паттерны, паттерны взаимодействия, паттерны создания объектов (фабрики) и др. Flux это просто пример, как зная эти паттерны, можно наладить взаимодействие между компонентами и организовать приложение.
Критика по делу и указание на неточности приветствуется.
Литература
Кому интересно, рекомендую к прочтению пару книг (ссылки сами знаете где найти), если кто не читал их:
- Learn Javascript Design Patterns от Addy Osmani
- Javascript Patterns от Stoyan Stefanov
- О ReactJS
- О Flux
* Все картинки взяты на просторах интернета