From 99ae17a7157d4926971725dad9c742d2b1710ccd Mon Sep 17 00:00:00 2001 From: okuzawats Date: Fri, 20 Jan 2023 06:14:58 +0900 Subject: [PATCH] rename effect to event (#76) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rename effect to event * UiStateRendererをさくじょ --- .../feature/architecture/ViewModel.kt | 18 ++++----- .../feature/dog/view/MainActivity.kt | 35 +++++++++++----- .../feature/dog/view/UiStateRenderer.kt | 40 ------------------- .../feature/dog/viewmodel/MainViewModel.kt | 4 +- .../feature/architecture/ViewModelTest.kt | 10 ++--- .../feature/main/MainViewModelTest.kt | 2 +- 6 files changed, 41 insertions(+), 68 deletions(-) delete mode 100644 feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/UiStateRenderer.kt diff --git a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModel.kt b/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModel.kt index 4d0ed3e..2a27cdd 100644 --- a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModel.kt +++ b/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModel.kt @@ -7,12 +7,12 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow /** - * a subclass of [androidx.lifecycle.ViewModel] which has state and effect. + * a subclass of [androidx.lifecycle.ViewModel] which has state and event. * * @param STATE type that represent the state of the ViewModel. - * @param EFFECT type that represent the effect the ViewModel has. + * @param EVENT type that represent the event the ViewModel may have. */ -abstract class ViewModel : androidx.lifecycle.ViewModel() { +abstract class ViewModel : androidx.lifecycle.ViewModel() { private val _state: MutableStateFlow by lazy { MutableStateFlow(initialState()) } @@ -22,14 +22,14 @@ abstract class ViewModel : androidx.lifecycle.ViewModel */ val state: Flow get() = _state.asStateFlow() - private val _effect: MutableSharedFlow by lazy { + private val _event: MutableSharedFlow by lazy { MutableSharedFlow() } /** - * effect that the ViewModel has. + * event that the ViewModel may have. */ - val effect: Flow get() = _effect.asSharedFlow() + val event: Flow get() = _event.asSharedFlow() /** * initial state of the ViewModel. @@ -44,9 +44,9 @@ abstract class ViewModel : androidx.lifecycle.ViewModel } /** - * do effect + * an event occur */ - internal suspend fun doEffect(effect: EFFECT) { - _effect.emit(effect) + internal suspend fun onNewEvent(event: EVENT) { + _event.emit(event) } } diff --git a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/MainActivity.kt b/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/MainActivity.kt index 0540be3..b360934 100644 --- a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/MainActivity.kt +++ b/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/MainActivity.kt @@ -4,12 +4,19 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.Button import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface +import androidx.compose.material.Text import androidx.compose.runtime.collectAsState import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope +import com.okuzawats.cleanarchitecture.feature.dog.composable.ErrorView +import com.okuzawats.cleanarchitecture.feature.dog.composable.ImageView +import com.okuzawats.cleanarchitecture.feature.dog.composable.InitialView +import com.okuzawats.cleanarchitecture.feature.dog.composable.LoadingView import com.okuzawats.cleanarchitecture.feature.dog.mapper.PresentationToUiMapper import com.okuzawats.cleanarchitecture.feature.dog.navigation.MainNavigator import com.okuzawats.cleanarchitecture.feature.dog.viewmodel.MainViewModel @@ -26,9 +33,6 @@ class MainActivity : ComponentActivity() { @Inject internal lateinit var presentationToUiMapper: PresentationToUiMapper - @Inject - internal lateinit var uiStateRenderer: UiStateRenderer - @Inject internal lateinit var mainNavigator: MainNavigator @@ -37,8 +41,8 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - viewModel.effect.onEach { effect -> - when (presentationToUiMapper.toUi(effect)) { + viewModel.event.onEach { event -> + when (presentationToUiMapper.toUi(event)) { is UiEvent.NavigateToLicense -> { mainNavigator.toLicense() } @@ -54,13 +58,22 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { - viewState.collectAsState(initial = UiState.initial()) - .let { - uiStateRenderer.RenderAsComposable( - uiState = it, - onLicenseClicked = viewModel::onLicenseAction, - ) + val state = viewState.collectAsState(initial = UiState.initial()) + when (state.value) { + is UiState.Initial -> InitialView() + is UiState.Loading -> LoadingView() + is UiState.Image -> { + Column { + Button(onClick = viewModel::onLicenseAction) { + Text(text = "LICENSE") + } + ImageView( + imageUrl = (state.value as UiState.Image).url, + ) + } } + is UiState.Error -> ErrorView() + } } } } diff --git a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/UiStateRenderer.kt b/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/UiStateRenderer.kt deleted file mode 100644 index 6ec27a9..0000000 --- a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/view/UiStateRenderer.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.okuzawats.cleanarchitecture.feature.dog.view - -import androidx.compose.foundation.layout.Column -import androidx.compose.material.Button -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import com.okuzawats.cleanarchitecture.feature.dog.composable.ErrorView -import com.okuzawats.cleanarchitecture.feature.dog.composable.ImageView -import com.okuzawats.cleanarchitecture.feature.dog.composable.InitialView -import com.okuzawats.cleanarchitecture.feature.dog.composable.LoadingView -import javax.inject.Inject - -/** - * renders [UiState] as Composable - */ -class UiStateRenderer @Inject constructor() { - @Composable - fun RenderAsComposable( - uiState: State, - onLicenseClicked: () -> Unit, - ) { - when (uiState.value) { - is UiState.Initial -> InitialView() - is UiState.Loading -> LoadingView() - is UiState.Image -> { - Column { - Button(onClick = onLicenseClicked) { - Text(text = "LICENSE") - } - ImageView( - imageUrl = (uiState.value as UiState.Image).url, - ) - } - } - is UiState.Error -> ErrorView() - else -> Unit - } - } -} diff --git a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/viewmodel/MainViewModel.kt b/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/viewmodel/MainViewModel.kt index a9cd5bd..b3f8ea7 100644 --- a/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/viewmodel/MainViewModel.kt +++ b/feature/randomdogimage/src/main/java/com/okuzawats/cleanarchitecture/feature/dog/viewmodel/MainViewModel.kt @@ -21,7 +21,7 @@ class MainViewModel @Inject constructor( onNewState(MainViewModelState.Loading) getRandomDogImageUseCase() .map(domainToPresentationMapper::toPresentation) - .map(MainViewModelState.Companion::from) + .map(MainViewModelState::from) .onEach(::onNewState) .launchIn(this) } @@ -29,7 +29,7 @@ class MainViewModel @Inject constructor( fun onLicenseAction() { viewModelScope.launch { - doEffect(MainViewModelEvent.NavigateToLicense) + onNewEvent(MainViewModelEvent.NavigateToLicense) } } diff --git a/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModelTest.kt b/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModelTest.kt index 57a699d..d4258f2 100644 --- a/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModelTest.kt +++ b/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/architecture/ViewModelTest.kt @@ -26,7 +26,7 @@ class ViewModelTest { } @Test - fun onNewState_update_state() = runTest { + fun when_state_is_updated_it_observed() = runTest { target.state.test { target.onNewState(0) @@ -41,14 +41,14 @@ class ViewModelTest { } @Test - fun doEffect_do_emits() = runTest { - target.effect.test { - target.doEffect(0) + fun when_event_happen_it_observed() = runTest { + target.event.test { + target.onNewEvent(0) assertThat(awaitItem()) .isEqualTo(0) - target.doEffect(42) + target.onNewEvent(42) assertThat(awaitItem()) .isEqualTo(42) diff --git a/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/main/MainViewModelTest.kt b/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/main/MainViewModelTest.kt index 10441cd..05949f8 100644 --- a/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/main/MainViewModelTest.kt +++ b/feature/randomdogimage/src/test/java/com/okuzawats/cleanarchitecture/feature/main/MainViewModelTest.kt @@ -112,7 +112,7 @@ class MainViewModelTest { @Test fun onLicenseAction_emits_NavigateToLicense_event() = runTest { - target.effect.test { + target.event.test { target.onLicenseAction() assertThat(awaitItem())