Is there any way kotlin lang features can help me ...
# getting-started
c
Is there any way kotlin lang features can help me simplify using a builder pattern (from java code) that needs IF checks around two of the chained methods? Examp;e: SomeBuilder(). .addA() <=== this should be conditional .addB() .addC() .addD() <=== this should be conditional I can split it apart, but somehow doing it inline would be a lot cleaner
h
Is the builder mutable (mostly the case) returning
this
or do you get a new builder after each
.addX()
? If mutable, just use
apply
c
looks like a new builder. let me try apply though. forgot about that
p
I some times face these problem. More specifically to instantiate an object that requires the dependecies in certain order. What I do is split the process in several build steps. Sort of: B1, B2, B3 Then do B1.start() // it returns B2 .doB2Stuff() // returns B3 . build() // returns the desired object.
c
yeah, I think the apply option should work in my case. even though i do get a new builder each time the compiler doesn't seem to complain.
p
Sounds good. My technique above is more oriented to, when the dependencies require specific order.
c
yeah. im basically writing a long builder from Android, but there are a bunch of api versino checks i have to write. if i dont write them, then i crash, so i just need some conditionals
k
Just because the compiler doesn't complain, it doesn't mean the
apply
method worked as you intended. If each builder method returns a new builder, then using
apply
will work but you won't actually build anything. This is what happens:
Copy code
val obj = SomeBuilder().apply {
    if (cond1) addA() // returns a new instance, which gets discarded
    addB() // returns another new instance, which gets discarded
    build() // builds the original empty object without addA or addB
}
👍 2
A possible workaround:
Copy code
val obj = SomeBuilder()
    .let { if (cond1) it.addA() else it }
    .addB()
    .build()
plus1 1
a
I would be very surprised if anyone creates an immutable builder class as there are literally zero advantages.
c
Hm. Maybe someone can help then because I'm trying with this https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder
And it's kinda tough to tell if it worked or not.
So I'm trying to string a bunch of detect statements
k
c
Detect all is not what I'm using though. I'm using all of the fine grained detect methods. I will try to look closer when I'm back at my desk
y
I think defining a
runIf
might be good here.
Copy code
inline fun <T> T.runIf(condition: Boolean, block: T.() -> T): T = if(condition) block(this) else this
Edited to actually make it a
run
🤦🏼‍♂️
👍 3
d
I would use
block: T.()->T
personally, since you won't need to use
it.
in the lambda.
builder.runIf(someVersion) { useVersionFeature() }
y
Agreed. That was my intention, but I messed it up lol
😁 1
c
okay. it does look like the "enable" method returns this. so i should be good with apply. thank you all
k
All of this confusion was caused by poor Android documentation. If it explicitly specified that it returned
this
, we wouldn't be discussing this.
c
I suppose I still forgot that apply was the right thing to use. so @hfhbd tip was helpful 😄