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