Reacción - resultados del método de manejo en Kotlin

Cualquiera que haya utilizado Clean Architecture en desarrollo se ha enfrentado al problema de transferir datos entre capas. La esencia del problema es siempre la misma: debe devolver un resultado o un error. Esto se puede representar, por ejemplo, así:





interface Reaction

data class Success(val data: String) : Reaction
data class Error(message: String) : Reaction
      
      



Dependiendo de la tarea, tales reacciones pueden ser muy diferentes, así que combinémoslas en una clase usando clases genéricas y selladas .





sealed class Reaction<out T> {
   class Success<out T>(val data: T) : Reaction<T>()
   class Error(val exception: Throwable) : Reaction<Nothing>()
}
      
      



Veamos un ejemplo de cómo se puede utilizar.





class MyViewModel : ViewModel {
	private val repository: Repository
	
	fun doSomething() {
		viewModelScope.launch(Dispatchers.IO) {
			val result = repository.getData()
			when (result) {
				is Success -> //do something
				is Error -> // show error
			}
		}
	}
}
      
      



. .





class RepositoryImpl(private val dataSource: DataSource) : Repository {
  
	override suspend fun getData(): Reaction<Int> {
		return try {
			Reaction.Success(dataSource.data)
		} catch(e: Exception) {
			Reaction.Error(e)
		}
	}
}

      
      



- , Reaction, try-catch, - . , try-catch .





sealed class Reaction<out T> {

   class Success<out T>(val data: T) : Reaction<T>()
   class Error(val exception: Throwable) : Reaction<Nothing>()

   companion object {
       inline fun <T> on(f: () -> T): Reaction<T> = try {
           Success(f())
       } catch (ex: Exception) {
           Error(ex)
       }
   }
}
      
      



:





class RepositoryImpl(private val dataSource: DataSource) : Repository {

	suspend fun getData(): Reaction<Int> = Reaction.on { dataSource.data }
}
      
      



, 4 .





ViewModel when . , View.





class MyViewModel : ViewModel {
	private val repository: Repository
	private val _onData = MutableLiveData<State>()
	val onData: LiveData<State> = _onData

	fun doSomething() {
		viewModelScope.launch(Dispatchers.IO) {
			val result = repository.getData()
			when (result) {
				is Success -> _onData.postValue(State.Success)
				is Error -> onData.postValue(State.Error(result.message))
			}
		}
	}

	sealed class State {
  	object Progress : State()
  	object Success : State()
  	data class Error(message: String) : State()
	}
}
      
      



RxJava, Coroutines LiveData.

, , ViewModel , , zip, Reaction , LiveData





inline fun <T, R> Result<T>.zip(success: (T) -> R, error: (Exception) -> R): R =
   when (this) {
       is Reaction.Success -> success(this.data)
       is Reaction.Error -> error(this.exception)
   }
      
      



MyViewModel





class MyViewModel : ViewModel {
	private val repository: Repository
	private val _onData = MutableLiveData<State>()
	val onData: LiveData<State> = _onNewDirectory

	fun doSomething() {
		viewModelScope.launch(Dispatchers.IO) {
			repository.getData()
				.zip(
        	{ State.Success }, 
        	{ State.Error(result.message) }
        )
				.let { onData.postValue(it) }
		}
	}

	//...
}
      
      



, ViewModel , . View





:





class MyViewModel : ViewModel {
	//...
	fun doSomething() {
		viewModelScope.launch(Dispatchers.IO) {
			var firstData: Int = 0

			val reaction = repository.getData()
			when (reaction) {
				is Success -> firstData = reaction.data 
				is Error -> {
					onData.postValue(State.Error(reaction.message))
					return@launch
				}
			}

			val nextReaction = repository.getNextData(firstData)
      
			//..
		}		
	}
  
	//...
}
      
      



, callback hell, , Coroutines





class MyViewModel : ViewModel {
  //...
	fun doSomething() {
		viewModelScope.launch(Dispatchers.IO) {
			val firstData = repository.getData()
				.takeOrReturn {
					onData.postValue(State.Error(result.message)
					return@launch
				}
			val nextReaction= repository.getNextData(firstData)
      
			//..
		}		
	}
}
      
      



, :





  • on - Reaction





  • map -





  • flatMap - Reaction





  • doOnSuccess - , Reaction -









Github





3 .





  • Railway Kotlin

    :









    • 1





    :





    • try-catch





    • infix









  • Arrow-KT

    :









    :













    • ,





  • Result (Kotlin)

    :









    :









    • gradle, , Result, Kotlin





Reaction es una biblioteca ligera con un umbral mínimo de entrada. consta de 1 archivo, que proporciona la misma potencia que la solución de Kotlin, pero no contiene todas sus desventajas.





Github

https://github.com/taptappub/Reaction/








All Articles