Pull to refresh

Comments 9

Я веб-разработчик.
С ELM не знаком, но по описанию он похож на другую популярную архитектуру в вебе, которая появилась позже.
Я написал статью из двух частей, в которой указываю ее проблемные моменты (это редьюсеры и использование событий там, где нет необходимости):
habr.com/ru/post/546606
habr.com/ru/post/546628

Основное отличие стора/сторов у меня в том, что там нет редьюсеров и событий.
Нет необходимости создавать функцию-редьюсер, в которой реализуется функционал нескольких функций. Вместо одной большой функции с 3-мя Event, лучше сделать 3 отдельных функции. Имя события тогда не понадобится.
У функции уже есть имя, зачем ей передавать лишнюю информацию (имя события) о том, что именно эту функцию нужно вызвать? Это конечно в некоторых ситуациях может быть полезно (чтобы уменьшить зависимость; для тестов), но пригодится далеко не во всех проектах. Да и вызвать функцию и передать ей параметры можно по имени, указав его как строку (но это в JavaScript. Как в других языках – не знаю), не заводя событий.

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

Но, это применимо к вебу. Не знаю, насколько это применимо к мобильной разработке.
Если вы говорите о Redux, то он был вдохновлен как раз ELM архитектурой и поэтому во многом похож.

Спасибо за статьи. Возможно эти идеи можно переложить на android, сложно сказать сразу. В андроид мире по-другому устроена работа с View, но возможно это изменится с приходом jetpack compose. Так же есть разница в языках. Например, проблема нарушения принципа Liskov решается в kotlin с помощью sealed classes, которые позволяют проверять добавление новых типов на этапе компиляции. Вызывать функцию по имени тоже проблематично — kotlin статически типизированный язык.

Так же есть некоторые различия в архитектуре, одним разбением редюсера на функии не получится ограничиться. В вашем примере событие saveTodo не является чистой фукнцией. У нее есть явная зависимость на todoController и получается, что ее запуск имеет побочные эффекты. Например это усложнит ее тестирование, поскольку придется работать с зависимостями. У нас Reducer — полностью чистая функция и не имеет такой проблемы.

Да, я о Redux.

Вызывать функцию по имени тоже проблематично — kotlin статически типизированный язык.

Конечно, язык и стек в целом играет большую роль. Не знаю, есть ли в kotlin рефлексия, но хоть словари должны быть, чтобы динамически вызывать функции, обращаясь по строковому имени/ключу. Но это не понадобится, если не пишется какой-то универсальный код или нет необходимости в событиях. В моем примере контроллера методы обновления стора вызываются напрямую: store.someAction();

В вашем примере событие saveTodo не является чистой функцией.

Ну, это уже side effect во view и к сторам не относиться. Аналоги редьюсеров находятся здесь:

https://github.com/sergeysibara/mobx-react-4-layer-architecture/blob/master/src/core/stores/BaseEditStore.ts

например, setEditState. Сторонние зависимости и сайд-эффекты в нем отсутствуют.

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

Redux тоже со временем пришел к разделению редьюссеров на отдельные методы в объекте: https://redux-toolkit.js.org/api/createSlice

Я правильно понимаю, что это по сути те же самые идеи, что redux + side-effect manager (saga, например). Или в чём-то всё таки есть отличия?
В целом Redux вдохновлен ELM архитектурой и получается, что есть много общего. Отличия незначитильные и больше относятся к тому как именно структурирован код. Например, у нас нет выделенных middleware и actions, а весь код для упрощения вынесен в Reducer и Actor.
Мы думали о том, чтобы использовать корутины, когда начинали проект. Но на тот момент они не были готовы для production, flow был еще в альфе. Кроме этого пришлось бы бороться с порогом входа. Большинству наших разработчков пришлось бы переучиваться и на тот момент сложнее было нанимать разработчков, уже долго работавших с корутинами.
Класс! Жаль, что вы используете RxJava, а не корутины(((
Спасибо! Возможно добавим поддержку корутин в будущем, пока мы выложили то чем пользуемся сами, а у нас в стеке именно Rx
Sign up to leave a comment.