Почему я должен использовать Actions in Flux?

Приложение, которое я разрабатываю, изначально было построено с помощью Flux.

Однако со временем приложение стало сложнее поддерживать. Было очень большое количество действий. И обычно одно действие прослушивается только в одном месте (магазине).

Действия позволяют не писать весь код обработчика событий в одном месте. Итак, вместо этого:

store.handleMyAction('ha')
another.handleMyAction('ha')
yetAnotherStore.handleMyAction('ha')

Я могу написать:

actions.myAction('ha')

Но я никогда не использую действия таким образом. Я почти уверен, что это не проблема моего приложения.

Каждый раз, когда я вызываю действие, я мог бы просто вызвать store.onSmthHappen вместо action.smthHappen.

Конечно бывают исключения, когда одно действие обрабатывается в нескольких местах. Но когда это происходит, кажется, что что-то пошло не так.

Как насчет того, чтобы вместо вызова действий я вызывал методы прямо из хранилища? Не будет ли мое приложение таким гибким? Нет! Происходит просто переименовать (за редким исключением). Но какой ценой! При всех этих действиях становится намного сложнее понять, что происходит в приложении. Каждый раз при отслеживании обработки сложных действий мне приходится находить в магазинах, где они обрабатываются. Затем в этих Store я должен найти логику, которая вызывает другое действие. И так далее.

Теперь я прихожу к своему решению:

Есть контроллеры, которые вызывают методы из хранилищ напрямую. Вся логика как обрабатывать действие находится в Магазине. Также сохраняет вызовы WebAPI (как обычно одно хранилище, относящееся к одному WebAPI). Если событие должно обрабатываться в нескольких хранилищах (обычно последовательно), то контроллер обрабатывает это, организуя промисы, возвращаемые из хранилищ. Некоторые из последовательностей (обычно используемые) в частных методах сами по себе. И метод контроллеров может использовать их как простую часть обработки. Поэтому я никогда не буду дублировать код.

Методы контроллера ничего не возвращают (односторонний поток).

На самом деле контроллер не содержит логики как обрабатывать данные. Это только указывает где и в какой последовательности.

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

Основные (на мой взгляд) преимущества флюса все же здесь.

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

Кроме того, обработка событий становится более очевидной. Теперь я могу просто посмотреть на обработчик в контроллере и все становится понятно, да и отлаживать намного проще.

Вопрос в том:

Почему действия были созданы в потоке? И какие у них преимущества, которые я упустил?


person iofjuupasli    schedule 28.11.2014    source источник


Ответы (2)


Действия были реализованы для захвата определенного взаимодействия в представлении или с сервера, которое затем может быть отправлено в любое количество различных магазинов. Разработчики объяснили это на примере чата facebook. Есть хранилище сообщений и хранилище потоков. Когда действие, например. messagePost был отправлен, он был отправлен в оба хранилища, выполняющих различную работу по обновлению своих атрибутов. Threadstore увеличил количество непрочитанных сообщений, а messageStore добавил новое сообщение в свой массив сообщений.

Таким образом, в основном это направление одного действия для выполнения изменений данных в более чем одном хранилище.

person Max Bumaye    schedule 01.12.2014
comment
Новые сообщения можно помечать как непрочитанные. А затем посчитайте в хранилище потоков, сколько сообщений помечено как непрочитанные. - person iofjuupasli; 01.12.2014
comment
Я думаю, вы не поняли мою мысль: 1 действие отправляется и обновляет 2 хранилища. Это зависит от вас, как от архитектора программного обеспечения, чтобы это соответствовало вашему варианту использования. - person Max Bumaye; 01.12.2014
comment
Возможно, решение Facebook лучше. Но подобные ситуации обычно являются скорее исключением, чем правилом. Итак, должен ли я использовать архитектурное приложение на основе исключения? И создать так много действий, используемых только в нескольких случаях? Оккам был бы недоволен. - person iofjuupasli; 01.12.2014
comment
По сути, используя действия, вы обеспечиваете концентрацию логики приложения. Если вы не будете реализовывать действия, которые отправляются, вам придется напрямую вызывать методы ваших магазинов, что повышает вероятность ошибки. это связано с тем, что вы можете выполнить действие А в контроллере 1 и 2. - person Max Bumaye; 01.12.2014
comment
И возвращаясь к вашему реторическому вопросу: Итак, должен ли я использовать архитектурное приложение, основанное на исключении? Вы должны использовать архитектуру приложения на основе варианта использования - person Max Bumaye; 01.12.2014
comment
Или я могу использовать что-то вроде контроллера, который отправляет событие не как наблюдаемое, а императивным образом (поэтому не сохраняет подписку на dispather, но вызовы dispather хранят методы). Императивный код лучше, чем основанный на событиях, когда нет динамически подписывающихся\отписывающихся слушателей, и есть не более 2-3 слушателей. Может быть, это неправда. Но это мой вопрос о. Если я ошибаюсь, то где и почему? - person iofjuupasli; 01.12.2014
comment
Я думаю, что дело в том, чтобы предотвратить двунаправленный поток данных в целом. Это сделано для того, чтобы поддерживать код в сопровождении. Пример: Flux: Error accures — вы проверяете вызываемое действие, смотрите, куда оно отправляется, и проверяете логику в своих хранилищах, в которых вызывается действие. Non-Flux: вы ищете ошибку, не имея четкой идеи, с чего начать -> события запускаются повсюду, а методы вызываются в компонентах без какой-либо концентрации - вы просто теряете обзор. Flux поможет вам в этом, особенно в больших проектах. - person Max Bumaye; 01.12.2014
comment
Почему Flux лучше, чем non-flux, понятно. Но почему поток лучше, чем поток без действий? С dispather-controller намного проще обрабатывать ошибки - person iofjuupasli; 01.12.2014
comment
что вы имеете в виду под диспетчером-диспетчером? - person Max Bumaye; 01.12.2014
comment
Просто описал сообщение выше. что-то вроде контроллера, который отправляет событие не как наблюдаемое, а императивным образом (поэтому не сохраняет подписку на dispather, а вызывает dispather, хранит методы) И в вопросе. О контроллере - person iofjuupasli; 01.12.2014
comment
Хорошо, если честно, я не знаю действительно хорошего ответа на этот вопрос. Я думаю, причина в том, чтобы ваши вещи были более модульными и гибкими (также учитывая порядок выполнения, который может отличаться в вариантах использования), но это необходимо только в более крупных проектах. Я думаю, что использование этого метода просто дает вам лучший способ масштабировать ваше приложение по мере его роста и только в том случае, если оно растет... но я думаю, что может быть гораздо больше мнений по этому поводу, которые должны быть вовлечены в это обсуждение. - person Max Bumaye; 01.12.2014
comment
Основное отличие, которое я вижу, заключается в том, что подход «диспетчер вызывает методы хранилища» требует, чтобы вся информация о том, какие хранилища следует вызывать и как они должны изменяться в ответ на каждое событие, собиралась в диспетчере. Действия позволяют распространять эту информацию по хранилищам, так что каждому хранилищу нужно просто знать о себе и своих зависимостях, а не диспетчеру нужно знать обо всех хранилищах и их зависимостях. - person Adam Stone; 17.02.2015
comment
Оккам был бы недоволен - прекрасно сказано! - person Daniel Earwicker; 03.04.2015
comment
Это очень большой вопрос, нужны ли отдельное хранилище потоков и хранилище сообщений, поскольку они, похоже, имеют одни и те же данные. Непрочитанные сообщения также могут быть вычислены хранилищем сообщений. Я тоже хотел бы увидеть реальный вариант использования для разных магазинов с ортогональными доменами, заинтересованными в одном и том же действии. - person w00t; 24.05.2015

У меня были те же вопросы и мыслительный процесс, что и у вас, и теперь я начал использовать Flummox, что упрощает Потоковая архитектура.

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

Он поставляется с хорошим FluxComponent, который позволяет вам объединить весь код, связанный с магазином, в одном месте, чтобы его дочерние элементы были компонентами без состояния, которые обновляются при изменениях в магазине, например

  <FluxComponent connectToStores={['storeA', 'storeB']}>
    <InnerComponent />
  </FluxComponent>

Мы надеемся, что сохранение архитектуры Flux (она использует за кулисами Flux Facebook) упростит использование других технологий, таких как GraphQL.

person w00t    schedule 06.06.2015