Sobes.tech
Middle

Cos'è il pattern di progettazione Factory e come viene utilizzato nella costruzione di oggetti (Builder)?

sobes.tech AI

Risposta dell'AI

Il pattern Factory Method fornisce un'interfaccia per creare oggetti nella classe base, consentendo alle sottoclassi di modificare il tipo di oggetti creati. ConcreteFactory decide quale ConcreteProduct creare.

Builder separa la costruzione di un oggetto complesso dalla sua rappresentazione. Permette di creare l'oggetto passo dopo passo, fornendo diversi metodi per impostare le sue proprietà e restituendo l'oggetto completo. È usato quando l'oggetto ha molti parametri opzionali e la sua creazione richiede logica complessa.

La fabbrica crea oggetti completi, mentre il builder li crea pezzo per pezzo.

Esempio:

// 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)"
    }
}

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

println(pizza)

Confronto:

Caratteristica Factory Method Builder
Scopo Creare oggetti tramite interfacce in sottoclassi. Creazione passo passo di oggetti complessi.
Complessità dell'oggetto Solitamente oggetti semplici. Oggetti complessi con molteplici parametri.
Flessibilità di creazione Selezione del tipo di oggetto in base alla sottoclasse. Configurazione progressiva delle proprietà dell'oggetto.
Restituzione dell'oggetto Restituisce un oggetto pronto. Restituisce un oggetto dopo la costruzione.
Applicazioni Framework, librerie, quando il tipo di oggetto non è noto in fase di compilazione. Oggetti con molti parametri opzionali.