在 kotlin 中从干净的架构定义用例的惯用方法
Idiomatic way to define use cases from clean architecture in kotlin
我尝试将我的用例 classes 从 Java 切换到 Kotlin,从 Rxjava 切换到协程。
这是我的 GetTopSongs
class.
class GetTopSongs {
suspend fun execute(limit:Int):Either<List<Song>>{
//... do stuff
}
}
我想知道在Kotlin中有没有比getTopSongs.execute(10)
更好的方法?
class GetTopSongs {
suspend operator fun invoke(limit:Int):Either<List<Song>>{
//... do stuff
}
}
因此您可以忽略额外的 .execute
调用:
val getTopSongs = GetTopSongs()
val result = getTopSongs(10)
如果您要使用 Kotlin 1.3,那么您可以使用 "callable references to a suspend function"。您向 ViewModel 构造函数提供函数类型:
class MyViewModel(val usecase: suspend (Int) -> List<Int>) {
suspend fun doIt() {
println(usecase(5))
}
}
您的用例可以归为一个或多个 类:
class MyUsecasses(val myRepo: MyRepo) {
suspend fun usecase1(para: Int): List<Int> = myRepo...
suspend fun usecase2(para: String): List<String> = myRepo...
}
创建 ViewModel 时提供函数参考:
val usecases = MyUsecasses(repo)
val viewmodel = MyViewModel(usecases::usecase1)
如果您不喜欢 ViewModel 构造函数中的函数类型,您可以使用类型别名:
typealias Usecase1 = suspend (Int) -> List<Int>
class MyViewModel(val usecase: Usecase1)
首先要注意的是 Either
是你在像 RxJava 这样的纯 FP API 中需要的拐杖。在某种程度上,将 map
和 skipUntil
等运算符链接起来会产生漂亮的代码,但您必须学习大量的运算符词汇表,并且在某些情况下您仍然需要其他东西。
Kotlin 协程的最大好处是您可以继续使用普通的旧命令式编程风格,并具有控制流语句的全部功能,包括 try-catch
。因此我推荐以下签名:
class GetTopSongs {
suspend operator fun invoke(limit:Int): List<Song> {
val result = ...
if (someProblem) throw MyException("problem description")
else return result
}
}
回到命令式风格的一个不太明显的好处是你不会 运行 陷入那些长达一页的类型推断错误。
我尝试将我的用例 classes 从 Java 切换到 Kotlin,从 Rxjava 切换到协程。
这是我的 GetTopSongs
class.
class GetTopSongs {
suspend fun execute(limit:Int):Either<List<Song>>{
//... do stuff
}
}
我想知道在Kotlin中有没有比getTopSongs.execute(10)
更好的方法?
class GetTopSongs {
suspend operator fun invoke(limit:Int):Either<List<Song>>{
//... do stuff
}
}
因此您可以忽略额外的 .execute
调用:
val getTopSongs = GetTopSongs()
val result = getTopSongs(10)
如果您要使用 Kotlin 1.3,那么您可以使用 "callable references to a suspend function"。您向 ViewModel 构造函数提供函数类型:
class MyViewModel(val usecase: suspend (Int) -> List<Int>) {
suspend fun doIt() {
println(usecase(5))
}
}
您的用例可以归为一个或多个 类:
class MyUsecasses(val myRepo: MyRepo) {
suspend fun usecase1(para: Int): List<Int> = myRepo...
suspend fun usecase2(para: String): List<String> = myRepo...
}
创建 ViewModel 时提供函数参考:
val usecases = MyUsecasses(repo)
val viewmodel = MyViewModel(usecases::usecase1)
如果您不喜欢 ViewModel 构造函数中的函数类型,您可以使用类型别名:
typealias Usecase1 = suspend (Int) -> List<Int>
class MyViewModel(val usecase: Usecase1)
首先要注意的是 Either
是你在像 RxJava 这样的纯 FP API 中需要的拐杖。在某种程度上,将 map
和 skipUntil
等运算符链接起来会产生漂亮的代码,但您必须学习大量的运算符词汇表,并且在某些情况下您仍然需要其他东西。
Kotlin 协程的最大好处是您可以继续使用普通的旧命令式编程风格,并具有控制流语句的全部功能,包括 try-catch
。因此我推荐以下签名:
class GetTopSongs {
suspend operator fun invoke(limit:Int): List<Song> {
val result = ...
if (someProblem) throw MyException("problem description")
else return result
}
}
回到命令式风格的一个不太明显的好处是你不会 运行 陷入那些长达一页的类型推断错误。