Created
February 14, 2025 22:39
-
-
Save audinue/28096aa9c05b8784a5670e4e3ae79dbd to your computer and use it in GitHub Desktop.
Clean architecture counter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.vorme.app.presentation.ui.screens.packages | |
| import androidx.compose.material3.Button | |
| import androidx.compose.material3.Text | |
| import androidx.compose.runtime.Composable | |
| import androidx.compose.runtime.LaunchedEffect | |
| import androidx.compose.runtime.mutableStateOf | |
| import androidx.compose.runtime.remember | |
| import cafe.adriel.voyager.core.screen.Screen | |
| interface CounterControllerInterface { | |
| fun increment() | |
| } | |
| interface CounterInputBoundary { | |
| @Composable | |
| fun displayCounter() | |
| fun increment() | |
| } | |
| interface CounterOutputBoundary { | |
| @Composable | |
| fun displayCounter(count: Int) | |
| } | |
| interface CounterDataAccessInterface { | |
| fun fetchCount(): Int | |
| fun increment() | |
| } | |
| class CounterController( | |
| val inputBoundary: CounterInputBoundary | |
| ) : CounterControllerInterface { | |
| override fun increment() { | |
| inputBoundary.increment() | |
| } | |
| @Composable | |
| fun displayCounter() { | |
| inputBoundary.displayCounter() | |
| } | |
| } | |
| class CounterUseCase( | |
| val outputBoundary: CounterOutputBoundary, | |
| val dataAccessInterface: CounterDataAccessInterface | |
| ) : CounterInputBoundary { | |
| val count = mutableStateOf(0) | |
| @Composable | |
| override fun displayCounter() { | |
| LaunchedEffect(true) { | |
| count.value = dataAccessInterface.fetchCount() | |
| } | |
| outputBoundary.displayCounter( | |
| count.value | |
| ) | |
| } | |
| override fun increment() { | |
| dataAccessInterface.increment() | |
| count.value = dataAccessInterface.fetchCount() | |
| } | |
| } | |
| class CounterView( | |
| val controllerInterface: Lazy<CounterControllerInterface?> | |
| ) { | |
| @Composable | |
| fun displayCounter(count: Int) { | |
| Button({ controllerInterface.value!!.increment() }) { | |
| Text(count.toString()) | |
| } | |
| } | |
| } | |
| class CounterPresenter( | |
| val view: CounterView | |
| ) : CounterOutputBoundary { | |
| @Composable | |
| override fun displayCounter(count: Int) { | |
| view.displayCounter(count) | |
| } | |
| } | |
| object CounterData { | |
| var count: Int = 7 | |
| } | |
| class CounterDataAccess : CounterDataAccessInterface { | |
| override fun fetchCount(): Int { | |
| return CounterData.count | |
| } | |
| override fun increment() { | |
| CounterData.count++ | |
| } | |
| } | |
| class CounterScreen : Screen { | |
| @Composable | |
| override fun Content() { | |
| var controller: CounterController? = null | |
| // Manual dependency injection | |
| controller = remember { | |
| CounterController( | |
| inputBoundary = CounterUseCase( | |
| outputBoundary = CounterPresenter( | |
| view = CounterView( | |
| controllerInterface = lazy { | |
| controller | |
| } | |
| ) | |
| ), | |
| dataAccessInterface = CounterDataAccess() | |
| ) | |
| ) | |
| } | |
| controller.displayCounter() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment