Итак, я переписываю код моего приложения, чтобы он был "чистым" (разделение слоев в соответствии с шаблоном MVVM, рекомендованным командой Android)
Здесь у меня есть простой интерфейс Retrofit для взаимодействия с моим API
interface Api {
@GET("comments")
suspend fun getPlaceComments(@Query("placeId") placeId: String): Response<List<CommentResponse>>
@POST("comments")
suspend fun addPlaceComment(@Header("placeId") placeId: String, @Header("text") text: String): Response<Unit>
@DELETE("comments")
suspend fun deletePlaceComment(@Header("placeId") placeId: String): Response<Unit>
}
Просто простой CRUD.
Теперь, на один уровень выше, у меня есть мой SocialRepository.Чтобы избежать повторения кода, я создал универсальный метод callSafely
, который принимает функцию API приостановки и placeId в качестве параметров.
class SocialRepository {
private val client: Api = ApiClient.webservice
private suspend fun <T> callSafely(
apiMethod: suspend (placeId: String) -> Response<T>,
placeId: String,
): T? {
Log.d(TAG, "$apiMethod called safely")
var response: Response<T>? = null
try {
response = apiMethod(placeId)
} catch (e: Exception) {
e.printStackTrace()
}
if (response?.isSuccessful != true) {
Log.w(TAG, "response.isSuccessful isn't true.")
}
return response?.body()
}
suspend fun getPlaceComments(placeId: String): List<CommentResponse>? {
return callSafely(client::getPlaceComments, placeId)
}
suspend fun deletePlaceComment(placeId: String): Unit? {
return callSafely(client::deletePlaceComment, placeId)
}
suspend fun addPlaceComment(placeId: String, text: String): Unit? {
return callSafely(client::addPlaceComment, placeId, text) // HERE LIES THE PROBLEM
// I can't pass additional data because the method signature won't match with what's defined in callSafely()
}
}
Теперь он работает довольно хорошо, конечно, у меня есть и моя активностьи его ViewModel и ViewModel вызывают метод в хранилище и т. д. Это не имеет значения.
Важно то, что для добавления комментария к месту требуются дополнительные данные, такие как фактический текст комментария.Для получения и удаления комментариев требуется только placeId, тогда как при добавлении комментария необходимо указать его содержимое text
.Я читал, что передача функций vararg
невозможна в Kotlin.Я также не хотел бы загромождать все методы API чем-то вроде List of params
, который в большинстве случаев будет пустым и просто создаст путаницу.
Я могу пойти простым путем и просто скопировать кодот callSafely
до addPlaceComment
и измените его, но это не то, что я ищу.Я знаю, как решить проблему, но я не знаю, как это сделать the clean way
.В будущем я мог бы добавить еще несколько конечных точек, требующих дополнительных данных (кроме placeId
), и проблема снова появится.
Что бы вы сделали в этой ситуации?Как написать это «правильным способом»?
Я даже не уверен, как правильно выразить то, что я ищу, вот почему этот пост такой бессвязный.Извините за это заранее.Я действительно надеюсь, что вы можете мне помочь.