Sobes.tech
Middle

Parla del pattern di progettazione 'Builder'.

sobes.tech AI

Risposta dell'AI

Il pattern di progettazione "Builder" (Costruttore) è un pattern creazionale che consente di creare oggetti complessi passo dopo passo. Separa il processo di costruzione di un oggetto complesso dalla sua rappresentazione, in modo che lo stesso processo di costruzione possa creare diverse rappresentazioni.

Componenti principali:

  • Costruttore (Builder): Interfaccia o classe astratta che definisce i metodi per creare parti di un oggetto complesso.
  • Costruttore Concreto (Concrete Builder): Implementa l'interfaccia del Costruttore e fornisce un'implementazione concreta per costruire le parti dell'oggetto. Memorizza il risultato intermedio e fornisce un metodo per ottenere l'oggetto finito.
  • Direttore (Director): Componente opzionale. Definisce l'ordine in cui vengono chiamati i metodi del costruttore per creare l'oggetto. Non conosce i costruttori concreti.
  • Prodotto (Product): Oggetto complesso creato dal costruttore.

Applicazioni:

  • Quando il processo di creazione dell'oggetto è complesso e include molte fasi opzionali.
  • Quando è necessario creare diverse rappresentazioni di un stesso oggetto usando lo stesso processo di costruzione.
  • Quando il costruttore dell'oggetto ha molti parametri.

Esempio in Go:

// Product - oggetto complesso
type Product struct {
	PartA string
	PartB string
	PartC string
}

// Builder - interfaccia del costruttore
type Builder interface {
	BuildPartA()
	BuildPartB()
	BuildPartC()
	GetProduct() *Product
}

// ConcreteBuilder - costruttore concreto
type ConcreteBuilder struct {
	product *Product
}

func NewConcreteBuilder() *ConcreteBuilder {
	return &ConcreteBuilder{product: &Product{}}
}

func (cb *ConcreteBuilder) BuildPartA() {
	cb.product.PartA = "Parte A costruita"
}

func (cb *ConcreteBuilder) BuildPartB() {
	cb.product.PartB = "Parte B costruita"
}

func (cb *ConcreteBuilder) BuildPartC() {
	cb.product.PartC = "Parte C costruita"
}

func (cb *ConcreteBuilder) GetProduct() *Product {
	return cb.product
}

// Director - direttore (opzionale)
type Director struct {
	builder Builder
}

func NewDirector(builder Builder) *Director {
	return &Director{builder: builder}
}

func (d *Director) Construct() {
	d.builder.BuildPartA()
	d.builder.BuildPartB()
	d.builder.BuildPartC()
}

// Uso
// concreteBuilder := NewConcreteBuilder()
// director := NewDirector(concreteBuilder)
// director.Construct()
// product := concreteBuilder.GetProduct()
// fmt.Printf("Prodotto creato: %+v\n", product)

Vantaggi:

  • Isola il codice di costruzione dell'oggetto dal codice cliente.
  • Permette di cambiare la rappresentazione interna del prodotto senza modificare il codice cliente.
  • Permette di costruire l'oggetto passo dopo passo.
  • Semplifica la creazione di oggetti con molti parametri.

Svantaggi:

  • Aumenta la quantità di codice (classi/interfacce) per creare l'oggetto.
  • Potrebbe essere ridondante per oggetti semplici.