Stylianos Gakis
03/24/2022, 9:25 AMStylianos Gakis
03/24/2022, 9:25 AMFeatureManager
which could provide all the various stuff that may be coming from different sources.
I had some code that looks something like this (implementation details removed for brevity)
interface FeatureFlagProvider
interface LoginMethodProvider
interface FooProvider
class FeatureManager(
featureFlagProvider: FeatureFlagProvider,
loginMethodProvider: LoginMethodProvider,
fooProvider: FooProvider,
) : FeatureFlagProvider by featureFlagProvider,
LoginMethodProvider by loginMethodProvider,
FooProvider by fooProvider
Which does what I want I think, I can inject this and have access to all the features I want.
I wanted to then try to make FeatureManager
an interface instead (maybe I wouldn’t need to, since I can just fake all the providers instead in tests I guess, but at this point I am just curious for the feasibility of it, or if I am going down a weird path.)
Something like this
interface FeatureManager : FeatureFlagProvider, LoginMethodProvider, FooProvider
But then if I were make an imlpementation of it like this class FeatureManagerImpl : FeatureManager
I don’t see how I could achieve the same delegation behavior 🤔
This doesn’t work
class FeatureManagerImpl(
featureFlagProvider: FeatureFlagProvider,
loginMethodProvider: LoginMethodProvider,
fooProvider: FooProvider,
) : FeatureManager by ???
And if I make it receive a FeatureManager directlty class FeatureManagerImpl(featureManager: FeatureManager) : FeatureManager by featureManager
I don’t see a simple way to create this instance without actually implementing all the funtions and deferring to the appropriate interface instead of doing this convenient by
delegation. Something like
val someFeatureFlagProviderImpl: FeatureFlagProvider = TODO()
val someLoginMethodProviderImpl: LoginMethodProvider = TODO()
val someFooProviderImpl: FooProvider = TODO()
val fm = FeatureManagerImpl(
object : FeatureManager {
override fun featureFlagProviderProvide() {
someFeatureFlagProviderImpl.featureFlagProviderProvide()
}
override fun loginMethodProviderProvide() {
someLoginMethodProviderImpl.loginMethodProviderProvide()
}
override fun fooProviderProvide() {
someFooProviderImpl.fooProviderProvide()
}
}
)
Stylianos Gakis
03/24/2022, 9:26 AMefemoney
03/24/2022, 10:01 AMclass FeatureManagerImpl(
featureFlagProvider: FeatureFlagProvider,
loginMethodProvider: LoginMethodProvider,
fooProvider: FooProvider,
) : FeatureManager,
FeatureFlagProvider by featureFlagProvider,
LoginMethodProvider by loginMethodProvider,
FooProvider by fooProvider
Stylianos Gakis
03/24/2022, 10:17 AMFeatureManager
which allows us to use it as an object of that type as well. And I see that if I remove one of the by
or if I remove that entire line so that it doesn’t implement that interface, then it does correctly prompt me to implement that one interface.
Feels a bit like magic to me but it works 😅 Definitely didn’t think I’d come up with this syntax myself, and I feel like I haven’t seen almost anyone using this by
syntax in the wild for implementing interfaces.
Thank you a lot for helping out!efemoney
03/24/2022, 10:25 AMStylianos Gakis
03/24/2022, 10:27 AM