Sobes.tech
Middle

What is the Factory design pattern and how is it used in object construction (Builder)?

sobes.tech AI

Answer from AI

The Factory Method pattern provides an interface for creating objects in the base class, allowing subclasses to alter the type of objects that will be created. ConcreteFactory decides which ConcreteProduct to create.

Builder separates the construction of a complex object from its representation. It allows creating an object step-by-step, providing various methods to set its properties and returning the finished object. It is used when an object has many optional parameters and its creation requires complex logic.

The factory creates objects as a whole, while the Builder creates them in parts.

Example:

// Factory Method
interface Dialog {
    fun createButton(): Button
    fun render() {
        val okButton = createButton()
        okButton.render()
    }
}

class WindowsDialog : Dialog {
    override fun createButton(): Button {
        return WindowsButton()
    }
}

class WebDialog : Dialog {
    override fun createButton(): Button {
        return HTMLButton()
    }
}

interface Button {
    fun render()
    fun onClick()
}

class WindowsButton : Button {
    override fun render() {
        println("Rendering Windows button")
    }

    override fun onClick() {
        println("Clicking Windows button")
    }
}

class HTMLButton : Button {
    override fun render() {
        println("Rendering HTML button")
    }

    override fun onClick() {
        println("Clicking HTML button")
    }
}

// Builder
class Pizza private constructor(
    private val size: String,
    private val cheese: Boolean,
    private val pepperoni: Boolean,
    private val mushrooms: Boolean
) {
    data class Builder(
        var size: String = "medium",
        var cheese: Boolean = false,
        var pepperoni: Boolean = false,
        var mushrooms: Boolean = false
    ) {
        fun size(size: String) = apply { this.size = size }
        fun cheese(cheese: Boolean) = apply { this.cheese = cheese }
        fun pepperoni(pepperoni: Boolean) = apply { this.pepperoni = pepperoni }
        fun mushrooms(mushrooms: Boolean) = apply { this.mushrooms = mushrooms }
        fun build() = Pizza(size, cheese, pepperoni, mushrooms)
    }

    override fun toString(): String {
        return "Pizza(size='$size', cheese=$cheese, pepperoni=$pepperoni, mushrooms=$mushrooms)"
    }
}

// Using Builder
val pizza = Pizza.Builder()
    .size("large")
    .cheese(true)
    .pepperoni(true)
    .build()

println(pizza)

Comparison:

Characteristic Factory Method Builder
Purpose Creating objects via subclassed interfaces. Step-by-step creation of complex objects.
Object complexity Usually simple objects. Complex objects with many parameters.
Creation flexibility Choosing object type depending on subclass. Stepwise property configuration of the object.
Object return Returns a finished object. Returns a finished object after construction.
Application Frameworks, libraries where object type is unknown at compile time. Objects with many optional parameters.
What is the Factory design pattern and how is it used… - sobes.tech