Где выполнять изменения состояния с помощью чистой архитектуры во Flutter?

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

введите описание изображения здесь

(В качестве примера я написал пакет MobX, но это может быть что угодно вроде BLoC, Redux ...)

У меня могут возникнуть проблемы с этой диаграммой, поскольку Магазин находится на уровне представления и отвечает за изменение состояния.

Представьте, что приложение загружает список задач с помощью метода getTodos Implementend в TodosStore. Реализация getTodos может быть такой:

 _state = State.loading();
 final result = GetTodos();
 _state = State.done();

(Я слишком упрощал)

Он начинается с обновления состояния до загрузки, вызывает вариант использования, возвращающий список, и устанавливает состояние в состояние «Готово».

Проблемы, которые я нашел здесь:

  1. Магазины несут ответственность за вызов UC, обновление состояния, обработку ошибок ...
  2. Вариант использования - это просто мост, который не обрабатывает бизнес-логику

Это довольно простой пример. Но давайте представим, что у меня есть представление с тремя списками разных данных (это может быть абсурдный пример). Представление взаимодействует с 3 разными магазинами. На панели приложения есть кнопка. Его цель - очистить 3 списка.

Как добиться такого поведения?

  • Метод кнопки onPressed должен будет вызывать clearData для каждого магазина.
  • Метод очистки каждого магазина просто обновит его свойства.

Дело в том, что вид не такой тупой, как хотелось бы. Магазин даже не взаимодействует ни с одним вариантом использования

Должен ли быть здесь законный вариант использования ClearLists?

Поскольку мне не нравится много логики на уровне представления, я стараюсь следовать этой диаграмме:

введите описание изображения здесь

Каждое представление имеет свою собственную ViewModel. ВМ просто взаимодействует с вариантом использования. Эти UC могут возвращать или не возвращать значение. Например: мой UC - это ValidateNumberRange, я могу не взаимодействовать с магазином. Имеет смысл вернуть bool. Но если мой UC - ClearTodoList, он может взаимодействовать с магазином. Успех или неудача могут быть сохраненным значением. Таким образом, возврат значения может оказаться бесполезным.

На этой новой диаграмме реализация вызываемого метода варианта использования GetTodos может быть следующей:

store.set(State.loading());
final result = repo.getTodos();
result.fold(
   (failureMsg) { store.set(State.failure(failureMsg)); },
   (newList) { store.set(State.done(newList)); },
);
  • Вариант использования обрабатывает логику управления состоянием
  • View вызывает метод виртуальной машины. Виртуальная машина вызывает UC и отслеживает изменения в Store (здесь через MobX)

Я задаю себе массу вопросов:

  • Правильно ли я понял роль UC в чистой архитектуре?
  • Считается ли изменение состояния (загрузка, выполнение, сбой) бизнес-логикой?
  • Где бы вы поместили решение для управления состоянием в своем приложении?

Я с нетерпением жду ваших мыслей


person Sxndrome    schedule 18.03.2021    source источник


Ответы (1)


Сценарии использования инкапсулируют бизнес-правила, и они не зависят от платформы и механизма доставки (например, UI). Сценарии использования основаны на функциональности, но без деталей реализации. Книга: https://dannorth.net/introduction-bdd

за изменение состояния отвечает уровень представления; Уровень презентации! = Уровень пользовательского интерфейса

Подумайте так:

Domain Layer <= infrastructure layer <= application layer <= presentation layer <= UI Layer

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

из вашей диаграммы: AppState и ViewModel всегда находятся на уровне представления. Специфические классы Flutter относятся к пользовательскому интерфейсу.

person Hashem Aboonajmi    schedule 19.03.2021
comment
Спасибо за ответ, Ашем. Что, если состояние не зависит от платформы? Я имею в виду, что у меня есть собственное решение состояния, которое не зависит от флаттера. Меня не совсем устраивало существующее решение для управления состоянием, которое слишком зависит от платформы. В моем случае код конкретной платформы (уровень представления) регистрируется только для хранения и наблюдает за изменениями, обеспечивая обратный вызов. Теперь этот код можно использовать внутри веб-проекта. Насколько я понимаю в вашем комментарии, он не уважает чистую арку, я прав? - person Sxndrome; 19.03.2021
comment
Уровень представления не зависит от платформы. так что вы можете использовать его повторно. не существует шаблона, называемого чистой архитектурой. Чистая архитектура - это концепция, которая побуждает вас отделить детали низкого уровня (фреймворки) от деталей высокого уровня (логика приложения) с помощью абстракций. поэтому вы можете легко заменять компоненты, если они соответствуют граничным интерфейсам. думайте так: вы должны иметь возможность легко изменить свой слой пользовательского интерфейса и иметь возможность повторно использовать свой код для Windows, Mac, Linux, Интернета, мобильных устройств. - person Hashem Aboonajmi; 19.03.2021