Kotlin Design Pattern: Builder
Tags: kotlin, design
Published: 2022-01-03 09:33:23

Hello Everyone,
I am starting to lean towards the declarative programming paradigm in Kotlin, also applying design patterns.

_[What is Imperative Programming?](https://www.freecodecamp.org/news/imperative-vs-declarative-programming-difference/#what-is-imperative-programming)_
You give the computer a set of instructions to follow and the computer does what you want in an easy-to-follow sequence.


_[What is Declarative Programming?](https://www.freecodecamp.org/news/imperative-vs-declarative-programming-difference/#what-is-imperative-programming)_
As a process of constantly defining what things are. This is referred to as declarative programming.


Some of the examples I found online it seems to me is in the form of imperative style. So I tried to construct a builder design pattern in declarative way with immutability in mind.

for the code example below

I declared an interface `DailySetup` with an implementation of data class `DailySetuImpl` as follows.

Then create a function `dailySetup` that returns an instance of `DailySetup` and accepts a higher order function that can access all properties of `DailySetupImpl`

---
_approach 1_
```kotlin
fun main() {
    val setup = dailySetup {
        constant = 1
        timeFunction = 1
        timeMult = 1
    }
    println("calculated setup: "+setup.calculate())
}

fun DailySetup.calculate(): Int {
    return (this.timeFunction*this.timeMult)+this.constant
}

interface  DailySetup {
    val constant: Int
    val timeFunction: Int
    val timeMult: Int
}

data class DailySetupImpl private constructor(
    override var constant: Int = 0,
    override var timeFunction: Int = 0,
    override var timeMult: Int = 0
): DailySetup {
    companion object {
        fun default () = DailySetupImpl()
    }
}

fun dailySetup(block: DailySetupImpl.()-> Unit): DailySetup {
    return DailySetupImpl.default().apply(block)
}
```
_approach 2_
```kotlin
fun main() {
    val setup = DailySetupBuilder.create {
        constant = 1
        timeFunction = 1
        timeMult = 1
    }
    println("calculated setup: "+setup.calculate())
}

fun DailySetup.calculate(): Int {
    return (this.timeFunction*this.timeMult)+this.constant
}

interface  DailySetup {
    val constant: Int
    val timeFunction: Int
    val timeMult: Int
}


data class DailySetupImpl private constructor(
    override var constant: Int = 0,
    override var timeFunction: Int = 0,
    override var timeMult: Int = 0
): DailySetup {
    companion object {
        fun default () = DailySetupImpl()
    }
}

class DailySetupBuilder {
    companion object {
        fun create(block: DailySetupImpl.()-> Unit): DailySetup {
            return DailySetupImpl.default().apply(block)
        }
    }
}
```

_approach 3_
we can utilize sealed classes, sealed classes cannot be explicitly initialized 
```kotlin
...
sealed class DailySetupImpl(
    override var constant: Int = 0,
    override var timeFunction: Int = 0,
    override var timeMult: Double = 0.0,
    override var internalObj: SetupInternalObj? = null
): DailySetup {
    object DEFAULT: DailySetupImpl()
}
class DailySetupBuilder {
    companion object {
        fun create(block: DailySetupImpl.()-> Unit): DailySetup {
            return DailySetupImpl.DEFAULT.apply(block)
        }
    }
}

```
---
In this way, I think, it is created via declarative way. What do you think of this approach?