Skip to content

Instantly share code, notes, and snippets.

@rongi
Last active April 17, 2019 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rongi/72fccf7a450c35bafb31fd2d4f5672ba to your computer and use it in GitHub Desktop.
Save rongi/72fccf7a450c35bafb31fd2d4f5672ba to your computer and use it in GitHub Desktop.
import android.app.Activity
import android.os.Bundle
import io.reactivex.Observable
import okhttp3.OkHttpClient
class MyActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val getUser: (userId: String) -> Observable<User> = dependencies.provideGetUser()
val presenter = MyPresenter(getUser)
}
}
class MyPresenter(
private val getUser: (userId: String) -> Observable<User>
)
val dependencies: MyDependencies = MyDependenciesReal()
interface MyDependencies {
fun provideHttpClient(): OkHttpClient
fun provideGetUser(): (userId: String) -> Observable<User>
}
data class User(
val id: String,
val name: String
)
class MyDependenciesReal : MyDependencies {
private val okHttpClient: OkHttpClient by lazy(::OkHttpClient)
override fun provideHttpClient(): OkHttpClient = okHttpClient
override fun provideGetUser(): (userId: String) -> Observable<User> {
val okHttpClient = provideHttpClient()
// Given okHttpClient make an Observable that allows us to get the user.
return makeGetUser(okHttpClient)
}
}
fun makeGetUser(okHttpClient: OkHttpClient): (String) -> Observable<User> {
return { userId: String ->
// Just a fake implementation, real one should use the okHttpClient.
Observable.just(User(id = userId, name = "user name"))
}
}
@pakoito
Copy link

pakoito commented Apr 17, 2019

class MyPresenter<N>(with val uf: UserFetcher<N>)

interface UserFetcher<N> {
  fun String.getUser(): User
}

extension class MyNetworkfetcher<N>(with val n: Network<N>): UserFetcher<N> {
  override fun String.getUser() =
    // Network client accessible via the field `client`.
    // Note that it's generic and not OkHttp, you could fix Network<OkHttp> for that
    // Or just implement all the calls to OkHttp into Network and use delegation. So clean.
    Observable.just(User(id = userId, name = "user name"))
}

// As said above I'd implement the specific API you'll be calling from OkHttp as individual functions instead
// but let's go with the easy version instead
interface Network<N> {
 val client: N
}

extension object OkNetwork: Network<OkHttpClient> {
  override val client: OkHttpClient by lazy { OkHttpClient() }
}


class MyActivity : Activity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val presenter = MyPresenter<OkHttp>()
  }
}

class MyTest {
  fun testSomething() {
    val fakeNw = object: UserFetcher<Nothing> {
      override fun String.getUser() = User("SO FAKE")
    }
    MyPresenter<Nothing>(fakeNw)
  }
}

@rongi
Copy link
Author

rongi commented Apr 17, 2019

Thank you @pakoito! About this

extension class OkNetwork: Network<OkHttpClient> {
  override val client: OkHttpClient by lazy { OkHttpClient() }
}

Should it be extension object instead of extension class if I want OkNetwork to be a singleton?

@pakoito
Copy link

pakoito commented Apr 17, 2019

Right. Fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment