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

Во-первых, немного предыстории. Я считаю себя разработчиком полного стека и уже несколько лет работаю с одностраничными приложениями. Я начал погружаться в React с самого начала его странных альфа-дней. Я выучил все зацепки, разжаловался и, к счастью, потерпел неудачу при кодировании приложения, достаточно сложного, чтобы оправдать необходимость в диспетчере состояний. Затем пришло время Redux: поскольку он быстро уладил все дебаты об архитектуре потока, я изучил все его концепции, разжаловался и, к счастью, потерпел неудачу в реализации надлежащего управления состоянием в новом блестящем проекте с Это.

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

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

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

Прелюдия

У меня всегда были проблемы с двумя шаблонами, которые кажутся мне очень присутствующими в сообществе JavaScript: концепции, абстракции и семантика обычно уступают удобству использования, практичности и синтаксису; Аккумуляторы обычно не входят в нашу повседневную упаковку, что приводит к тому, что владельцы упаковок не заботятся о том, как их упаковка соответствует миру.

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

Одна из проблем, на которые я указал в этой предыдущей статье, - это как раз расплывчатая семантика, которую мы имеем для Redux Actions. Чем больше я кодировал Elm в свободное время и внедрял его концепции в свой реальный код Redux, тем яснее мне становилось, что Elm все правильно. Кроме того, я не думаю, что это ситуация «они разные, но каждый занимается своим делом», по крайней мере, в этом вопросе. Я вижу, что тем, у кого больше опыта в Elm, лучше моделировать свои магазины, а тем, кто идет напрямую в Redux, сложнее. (что, в общем, все).

Итак, давайте попробуем восполнить этот пробел, не так ли?

Что такое действие?

Мы все к этому привыкли, правда? Насколько мы знаем, это простой объект. У него есть ключ обязательного типа, который сообщает нам, какое событие и какие данные он представляет. Посмотрим, что говорит Redux, исходя из своей документации.

Действия - это полезная информация, которая отправляет данные из вашего приложения в ваш магазин. Они являются единственным источником информации для магазина. Вы отправляете их в магазин с помощью store.dispatch ().

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

Так что давайте вместе подумаем. Я хочу написать простую форму, которая позволит мне изменить свой адрес электронной почты на какой-нибудь прорывной веб-платформе. Нам нужны текстовый ввод и кнопка отправки, с каждым действием по одному. Как назвать действия? Как насчет SET_EMAIL_TEXT и SUBMIT_EMAIL_FORM? Или даже CHANGE_EMAIL_TEXT и SAVE_EMAIL? А может REQUETS_EMAIL_CHANGE?

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

Связь, но для какой информации?

Мы узнали, что действия были частями коммуникации с нашим приложением, должным образом управляемыми Redux. Это предполагает, что действия - это способ общения, который имеет смысл.

Последующий вопрос, оставленный пользователям в качестве упражнения: для какой информации? Что мое приложение должно сообщать моему магазину?

По моему опыту, на этот вопрос есть два основных ответа. Большинство проектов демонстрируют сочетание двух: сообщения о намерениях и сообщения о событии. Один из них гораздо более распространен, чем другой, и я позволю вам угадать, какой именно, пока мы рассмотрим их в следующих разделах.

Действие сообщает намерение

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

Такой образ мышления широко распространен, и это не удивительно. Это очень хорошо согласуется с нашим императивным мышлением и кажется правильным с точки зрения программиста: для моего магазина имеет смысл распознавать CHANGE действие, если я пытаюсь что-то изменить, оно подходит. Или нет?

Семантика для Действия, которую мы оставили с этой точки зрения, очень близка к семантике, которая у нас есть для простых функций, верно? Это блок кода, который выполняет какое-то намерение. Более того, мы чувствуем себя хорошо, потому что действия позволяют нам мыслить императивно, в то время как React и Redux умоляли в пользу декларативности. Вот где все начинает сбиваться.

Если мы рассматриваем Действия и функции как близкие концепции, мы начинаем делиться некоторыми чертами, которые не соответствуют архитектуре Redux. Самая важная и вредная заключается в том, что функции предназначены для повторного использования, а действия должны быть очень контекстно-зависимыми. Следуя этому ходу мыслей, мы склонны думать о том, что наши действия можно использовать повторно, поэтому, возможно, REQUEST_EMAIL_CHANGE, который мы уже использовали в форме изменения пароля, может пригодиться, когда мне нужно изменить адрес электронной почты пользователя в зарегистрироваться. Использую в двух местах вместо одного!

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

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

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

Действие сообщает о событии

Да, я могу представить, как вы читаете это, поскольку это то, о чем мы говорили, когда jQuerying наш путь к успеху задолго до того, как пришли хипстеры. Дело в том, что в jQuery были плохие не события, а императивное мышление. Когда мы переходим на Redux и приносим с собой образ мышления, мы просто решаем проблему с помощью более сложных инструментов, избегая при этом реальной опасности: тьмы внутри нас. Так что притворите сюрприз и терпите меня, пока я пытаюсь нарисовать картину того, почему этот тип общения лучше.

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

Разница может показаться глупой, но на самом деле это не так: вы больше не будете называть Action SET, REQUEST или CHANGE, потому что эти имена явно передают намерение. Приложение должно просто сообщить об этом Магазину, так что INPUT_CHANGED или BUTTON_CLICKED ему больше нравится. Журнал действий будет выглядеть как серия взаимодействий, что больше похоже на архитектуру. Весь смысл наличия Store в том, что он станет сердцем и душой вашего приложения и будет знать, как справляться с точным количеством взаимодействий, поддерживаемых приложением.

Тот факт, что USER_SIGNED_UP и CHANGE_EMAIL_FORM_SUBMITTED оба сохраняют электронную почту пользователей, является просто совпадением бизнес-логики, которое наверняка будет абстрагировано до функции, чтобы избежать дублирования, но это не означает, что у них должно быть одно действие. Вы не будете склонны (или, по крайней мере, менее склонны) отправлять два Действия из одного взаимодействия, потому что это больше не имеет смысла. Одно взаимодействие (например, щелчок, тайм-аут или ответ сервера) - это одно действие, потому что действие представляет собой все взаимодействие, а не его намерения. Наконец, отправка одного Action из редукции другого будет казаться странной, например, это будет означать, что хранилище сигнализирует о событиях самому себе, что нарушает «действия как средство связи с внешним миром. ''.

Обдумывание действия и способа передачи событий заставит вас перейти от глаголов повелительной формы к глаголам в прошедшем времени. Изменение мышления позволит лучше согласовать моделирование вашего магазина с декларативной моделью мышления, которая, в свою очередь, будет лучше соответствовать архитектуре React и Redux.

Что же не так с названием Action?

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

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

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

В конечном итоге мы скатываемся к информирующему о намерении действию по отдаче приказов, потому что это кажется правильным. Этот образ мышления идеально сочетается с императивным программированием, которым мы дорожим с первых дней (и не без оснований). Это кажется знакомым, потому что мы уже находимся в совершенно другом месте по сравнению с тем, к чему мы привыкли, по крайней мере, мы можем заказать наш Магазин так, как мы знаем, работал на нас в прошлом. И, наконец, он идеально сочетается с названием «Действие», которое предполагает, что коммуникация должна что-то делать, должна вносить изменения, должна действовать.

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

Это не действие, это реакция. Это не приказы, а описание поведения. Это не обязательно, это декларативно. Вот почему Action - плохое имя для Redux Action.

Эпилог

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

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

Я думаю, что Message - лучшее название, чем Action для концепции, принятой в Redux, но не в этом суть. Дело в том, что человеческое понимание хрупко и может быть изменено мельчайшими деталями, поэтому мы можем сначала сосредоточить свое понимание на основополагающих концепциях, а затем на том, как применить их в нашем стартапе.

И эй, может я ошибся. Может быть, семантика отличается по какой-то причине, и я, а не Redux, упускаю из виду суть. Но тогда вам нужно сказать мне, и, пожалуйста, сделайте это!