Котлин, уменьшить дублированный код

Каждый мой интерфейс API-интерфейса службы создает статический метод,

interface AuthApiService { @FormUrlEncoded @POST("api/auth/login") fun postLogin(@Field("username") username: String, @Field("password") password: String): io.reactivex.Observable<LoginApiResponse> companion object Factory { fun create(): AuthApiService { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http:192.168.24.188:8080") .build() return retrofit.create(AuthApiService::class.java) } } } interface BBBApiService { companion object Factory { fun create(): BBBApiService { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http:192.168.24.188:8080") .build() return retrofit.create(BBBApiService::class.java) } } } 

Но я хочу определить метод create () только один раз.

Поэтому я сделал класс ApiFactory,

 interface ApiFactory { companion object { inline fun <reified T>createRetrofit(): T { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http://192.168.24.188:8080") .build() return retrofit.create(T::class.java) } } } interface AuthApiService { @FormUrlEncoded @POST("api/auth/login") fun postLogin(@Field("username") username: String, @Field("password") password: String): io.reactivex.Observable<LoginApiResponse> companion object Factory { fun create(): AuthApiService { return ApiFactory.createRetrofit() } } 

Но, тем не менее, мне нужно определить метод create () в AuthApiService.

Есть ли способ реализовать класс ApiFactory для классов SubApi, так что мне не нужно определять метод create в каждом дочернем классе?

Простое решение – просто вызвать функцию вашего ApiFactory напрямую:

 val authApiService = ApiFactory.createRetrofit<AuthApiService>() 

Но если вы хотите иметь возможность вызвать AuthApiService.create() , вы можете определить интерфейс маркера, скажем, ApiFactoryClient<T> , и пометить с ним пустой companion object .

 interface ApiFactoryClient<T> interface AuthApiService { /* ... */ companion object : ApiFactoryClient<AuthApiService> } 

А затем создайте функцию расширения, которая работает с ApiFactoryClient<T> :

 inline fun <reified T> ApiFactoryClient<T>.create(): T = ApiFactory.createRetrofit<T>() 

И использование будет:

 val authApiService = AuthApiService.create() 

Вы можете изменить свой ApiFactory следующим образом:

 interface ApiFactory { companion object { inline fun <reified T>createRetrofit(klass: KClass<T>): T { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http://192.168.24.188:8080") .build() return retrofit.create(klass.java) } } } 

Затем используйте его для создания различных экземпляров службы:

 val authApiService = ApiFactory.createRetrofit(AuthApiService::class)