← Назад к вопросам

Что такое Action в MVI?

2.0 Middle🔥 161 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Action в MVI?

В архитектуре MVI (Model-View-Intent) Action — это ключевой компонент, представляющий собой намерение или событие, инициированное пользователем или системой, которое приводит к изменению состояния приложения. Action служит входной точкой для бизнес-логики, преобразуя пользовательские взаимодействия или внешние события в предсказуемые и обрабатываемые команды для реактивной системы. В контексте MVI, Action часто ассоциируется с Intent (в оригинальной концепции из Cycle.js), но в современных Android-реализациях, таких как с использованием RxJava, Kotlin Flow или Coroutines, Action обычно является частью однонаправленного потока данных.

Роль Action в однонаправленном потоке данных

MVI строится на принципе однонаправленного потока данных, где:

  1. Пользователь или система генерирует Action (например, нажатие кнопки, получение push-уведомления).
  2. Action отправляется в обработчик (например, ViewModel, Interactor или Reducer).
  3. Обработчик преобразует Action в обновленное состояние (State).
  4. Новое State передается View для отображения.
  5. Цикл замыкается, обеспечивая предсказуемость и тестируемость.

Пример простого Action в Kotlin для задачи загрузки данных:

// Определение sealed-класса для Action
sealed class UserAction {
    object LoadUsers : UserAction()
    data class SearchUser(val query: String) : UserAction()
    data class DeleteUser(val userId: String) : UserAction()
}

// В ViewModel или Presenter
fun processAction(action: UserAction) {
    when (action) {
        is UserAction.LoadUsers -> loadUsers()
        is UserAction.SearchUser -> searchUser(action.query)
        is UserAction.DeleteUser -> deleteUser(action.userId)
    }
}

Отличие Action от State и Effect

В MVI важно различать три основных компонента:

  • Action: Входные события, которые запускают изменения (например, OnButtonClicked).
  • State: Неизменяемые данные, описывающие текущее состояние UI (например, LoadingState, DataState).
  • Effect: Побочные эффекты, такие как навигация или показ уведомлений, которые не являются частью State.

Пример State и Effect:

data class UserState(
    val isLoading: Boolean = false,
    val users: List<User> = emptyList(),
    val error: String? = null
)

sealed class UserEffect {
    object NavigateToDetails : UserEffect()
    data class ShowToast(val message: String) : UserEffect()
}

Преимущества использования Action в MVI

  • Предсказуемость: Все изменения State происходят через явные Action, что упрощает отладку и логирование.
  • Тестируемость: Action можно легко тестировать в изоляции, проверяя, как они преобразуются в State.
  • Масштабируемость: Добавление новых фич часто сводится к созданию новых Action и их обработке, без изменения существующей логики.
  • Декларативность: View просто отправляет Action, а бизнес-логика инкапсулирована в обработчиках.

Практическая реализация с Coroutines и Flow

В современных Android-приложениях Action часто обрабатываются с помощью Kotlin Coroutines и Flow. Пример с ViewModel:

class UserViewModel : ViewModel() {
    private val _state = MutableStateFlow(UserState())
    val state: StateFlow<UserState> = _state.asStateFlow()

    private val _effect = MutableSharedFlow<UserEffect>()
    val effect: SharedFlow<UserEffect> = _effect.asSharedFlow()

    fun onAction(action: UserAction) {
        when (action) {
            is UserAction.LoadUsers -> loadUsers()
            // Обработка других Action
        }
    }

    private fun loadUsers() = viewModelScope.launch {
        _state.update { it.copy(isLoading = true) }
        try {
            val users = userRepository.getUsers()
            _state.update { it.copy(isLoading = false, users = users) }
        } catch (e: Exception) {
            _state.update { it.copy(isLoading = false, error = e.message) }
            _effect.emit(UserEffect.ShowToast("Ошибка загрузки"))
        }
    }
}

Заключение

Action в MVI — это фундаментальный строительный блок, который обеспечивает структурированный и реактивный подход к обработке событий. Он способствует чистой архитектуре, разделяя ответственность между View, бизнес-логикой и состоянием, что особенно важно для сложных Android-приложений с большим количеством взаимодействий. Использование Action в сочетании с неизменяемым State и управляемыми побочными эффектами делает код более поддерживаемым, тестируемым и устойчивым к багам.

Что такое Action в MVI? | PrepBro