Замечание: Почему скриншоты вместо сниппетов кода? Просто красивее выглядит. Весь упоминаемый код находится на Github gist, а сама библиотека на pub.dev.
Reactive State Management в GetX сделан очень изящно и реализуется буквально в пару строк - одна в контроллере и одна во View, как-то так
Однако есть проблема. Этот подход нарушает принцип UDF, да в общем-то и все наперечет архитектурные паттерны приложений MVC/MVVM и далее по порядку в части взаимодействия View с состоянием модели. View не должна иметь возможность напрямую изменять это состояние. А в примере выше именно так и происходит.
Модель никак не модерирует состояние, View его изменила и тут же получила обратно. В данной реализации с этим ничего не поделать, так как переменная clickCounter
публична.
Конечно, в GetX как всегда находится решение, и оно достаточно простое - спрятать переменную за геттером и сеттером:
В этом случае принцип UDF восстановлен, мы имеем возможность управлять бизнес-логикой, прежде чем View получит результат.
В общем-то, на этом можно и остановиться, решение рабочее. Но...
Переменная разрослась до трех сущностей. А если кроме этого потребуется обращаться к ее стриму, то придется добавить еще и его:
Управлять 3-4 сущностями для каждой переменной то еще занятие. Многословно, чревато ошибками, не изящно.
Все эти вопросы (и не только) призван решить GetRxDecorator
.
GetRxDecorator как элегантный путь к UDF
Вместо четырех переменных как описано выше, можно написать что-то вроде этого
Мы заменяем 4 переменные на одну, инкапсулируя поведение в стиле ООП & UDF, исключая непреднамеренное нарушение доступа к изменению напрямую.
Этот подход реализует паттерн Decorator
вокруг Rx-переменной. В самом простом случае достаточно написать var rxVarInt = 1.obsDeco()
вместо var rxVarInt = 1.obs
.
Дополнительные возможности декоратора
Опциональный параметр
args
в сеттере и его колбеке
Он позволяет реализовывать нестандартную логику присвоения в определенных случаях.
К примеру, когда изменение значения происходит только в случае если аргумент либо не тип Int
, либо значение агрумента больше 1, то сеттер выглядит как-то так
а по тестам видно, что присвоение происходит верно
Параметр
oldValue
в колбеке сеттера
В колбек сеттера передается текущее значение переменной через параметр oldValue
. Используя его вместо (вместе) newValue
можно реализовывать необычные алгоритмы, основанные на текущем значении переменной, типа "Гипотезы Коллатца". Это может выглядеть как-то так:
(См. в тесте ‘Collatz conjecture setter test’ и в примере в библиотеке)
Опциональный параметр
forceRefresh
.
Этот параметр позволяет форсировать обновление неизмененной переменной.
Исходники и библиотека
Исходники можно посмотреть на GitHub gist
Так же решение оформлено, как часть библиотеки на pub.dev