反応-処理方法はKotlinになります

開発でクリーンアーキテクチャを使用したことのある人は誰でも、レイヤー間でデータを転送するという問題に直面しています。問題の本質は常に同じです。結果またはエラーのいずれかを返す必要があります。これは、たとえば次のように表すことができます。





interface Reaction

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



タスクによって、そのような反応は大きく異なる可能性があるため、GenericsクラスSealedクラスを使用して1つのクラスにまとめましょう





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



使い方の例を見てみましょう。





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は、エントリのしきい値が最小の軽量ライブラリです。これは1つのファイルで構成されており、Kotlinのソリューションと同じ機能を提供しますが、すべての短所が含まれているわけではありません。





Github

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








All Articles