Обновить

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

Проблема, озвученная в заголовке понятна, но примеры по-моему выбраны не совсем удачно.

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

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

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

Про мультиплексирование не ограниченного числа каналов через один код по разным ключам будет отдельная статья.

Например, можно требовать при создании состояния, чтобы все его зависимости уже существовали. Обычно так делают push-библиотеки типа RxJS или Effector.

В эффекторе связи принято создавать через sample(), т.е. в любой момент после создания сущностей и таким образом можно сущность даже саму на себя зациклить:

sample({
   source: $source,
   fn: (...) => { ... },
   target: $source
});

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

Зависит от того, что в функции маппинга и что передано в source/target. Если значения после мапа получаются не эквивалентные, то будет бесконечный цикл. Известная проблема, но авторы эффектора считают ее нерешаемой.

fahrenheit( fahrenheit )

Это оочень странный и крайне дурной api. Принимать фаренгейты для конвертации в фаренгейты, заодно конструировать фаренгейты пока конвертируешь в фаренгейты. Симметричнаяя структура и для цельсиев. Зачем там вообще ухищрения с кучей полей в разных метриках да ещё и кэшируемые? Казалось бы оставь какое-нибудь одно поле и кэшируй второе вычислимое поле. Сделай адекватный конструктор, а лучше два, чтобы точно знать какое из значений подаётся на вход и будет тебе счастье.

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

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

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

Публикации