Ahmed Mourad
04/16/2020, 10:09 AMinterface Manager { ... }
class ManagerImpl(...) : Manager {
override fun functionality(): SomeShenanigans {
return Shenanigans.create { ... }
}
...
}
2. Dividing implementation into multiple small functions
interface/typealias Functionality: () -> SomeShenanigans
fun functionalyImpl(): SomeShenanigans = Shenanigans.create { ... }
class ManagerImpl(f: Functionality, ...) : Manager {
override fun functionality(): SomeShenanigans {
return f.invoke()
}
...
}
The former is much more compact but can cause circular dependencies and would require some weird shenanigans to solve, while the later solves the issues with circular dependencies but would require much more boilerplate.tddmonkey
04/16/2020, 10:14 AMalexey_gusev
04/16/2020, 11:04 AMAhmed Mourad
04/16/2020, 11:24 AMAhmed Mourad
04/16/2020, 11:24 AMAuthManager
which depends on a RemoteRepository
to store the users' data an Authenticator
to do the actual authentication.
The problem is that the RemoteRepository
requires the user to be signed in for all of its functionalities so it would need to depend on the AuthManager
to check if the condition applies, which is bad design on its own but it would also introduce circular dependency between the RemoteRepository
and the AuthManager
.
I could move the authentication check to the AuthManager
but it feels like leaking implementation details to an outer layer.
I would really appreciate any suggestions on how to solve this.alexey_gusev
04/16/2020, 11:28 AMalexey_gusev
04/16/2020, 11:28 AMAhmed Mourad
04/16/2020, 11:52 AMoverride fun findSignedInUser(id: UserId): Flowable<Either<Throwable, SignedInUser?>> {
return observeUserAuthState()
.subscribeOn(<http://Schedulers.io|Schedulers.io>())
.observeOn(<http://Schedulers.io|Schedulers.io>())
.flatMap { isUserSignedIn ->
if (isUserSignedIn) {
createFlowable(id)
} else {
Flowable.just(NoUserException().left())
}
}.flatMap { ... }
alexey_gusev
04/16/2020, 12:35 PM