Pull to refresh

Comments 10

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

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

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

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

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

По-моему реактивность это про значения, которые меняются во времени. В вашей задаче такое только одно - это температура (пара вида [valve: T, measure: M]). Для решения достаточно одного Subject<[T, M]> и чистой функции, которая преобразует значение в заданную единцу измерения convertTo(M, [T, M]) -> [T, M].

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

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

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

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

fahrenheit( fahrenheit )

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

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

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

Какая прекрасная идея не хранить исходные данные, чтобы лепить костыли, дабы все преобразования были биекциями.

Sign up to leave a comment.

Articles