Изучение
Model и ModelBinding
Сборка единого неизменяемого снимка функции из одной или нескольких бизнес-границ без передачи инфраструктуры во View.
Model и ModelBinding
В Ark MVP намеренно нет универсального базового класса Model. Каждая функция определяет обычный неизменяемый тип, описывающий её полный актуальный снимок.
final class ProfileModel {
const ProfileModel({
required this.profile,
required this.saveState,
required this.reload,
required this.save,
});
final ProfileState profile;
final SaveProfileState saveState;
final void Function() reload;
final void Function(String name) save;
}
Model не является доменной сущностью или вторым менеджером состояния. Это снимок функции на границе представления, собранный из уже существующих бизнес-объектов.
Подключение состояния
final binding = ModelBinding<ProfileModel>(
read: () => ProfileModel(
profile: profileManager.state,
saveState: saveManager.state,
reload: profileManager.reload,
save: saveManager.save,
),
changes: <Stream<Object?>>[
profileManager.changes,
saveManager.changes,
],
);
Значения из changes служат сигналами, а не частичными обновлениями. После каждого сигнала размещающий компонент вызывает read() и получает новую полную Model. Presenter не нужно определять источник события или поддерживать второй алгоритм слияния состояний.
Требования к снимку
read()выполняется синхронно;- возвращённая Model должна оставаться неизменной;
- каждое чтение описывает функцию целиком;
- владельцем Stream остаётся приложение;
ModelBindingне создаёт транзакцию между независимыми менеджерами.
Если несколько значений обязаны изменяться атомарно, их следует объединить за одной бизнес-границей до передачи в MVP.
Обратные вызовы или интерфейс действий
Для небольшой Model подходят конкретные обратные вызовы. Более крупная функция может объявить типизированный интерфейс действий. В обоих случаях наружу выходят разрешённые операции функции, а не произвольный доступ к инфраструктуре.