Una chiave per comprendere i modelli di progettazione GoF è la loro intenzione. Per il costruttore è:
Separate the construction of a complex object from its representation
so that the same construction process can create different
representations
Variante semplificata
Quando guardi la soluzione proposta da GoF, ciò che colpisce di più è la costruzione separata e l'assemblaggio delle parti: la struttura distingue Director
e Builder
e abilita una costruzione passo passo:
- Questo aspetto del pattern sembra accarezzare Joshua Bloch , perché il suo approccio usa questa separazione per impostare molti parametri opzionali.
- Questa sequenza di eventi consente anche di convalidare le parti prima di assemblare il risultato, come hai notato in questo XmlBuilder.
Pur essendo molto utile, penso comunque che questi esempi si concentrino solo su un aspetto del modello e perdano il vero intento. Pertanto, la loro struttura appare semplificata unendo Director
e Builder
o Builder
e ConcreteBuilder
.
L'intento mancante
Per GoF, non si tratta solo della separazione tra Director
e Builder
per costruire per passo, ma anche la separazione tra Builder
e ConcreteBuilded
:
- Se guardi bene struttura del pattern , noterai che
Builder
fornisce il polimorfico / metodi virtuali buildPart()
. Ma getResult()
per ottenere il prodotto finale è un metodo di ConcreteBuilder
che non è incluso nell'interfaccia dell'estratto Builder
. Quindi può utilizzare diversi parametri o restituire diversi tipi.
- Il diagramma sequenza GoF a pagina 99 mostra inoltre che
Client
chiama Director
per la costruzione dell'oggetto e attiva la costruzione di parti (magari usando oggetti temporanei), ma che spetta al client chiamare getResult()
direttamente da ConcreteBuilder.
- Infatti, il client conosce ConcreteBuilder (potrebbe essere anche istanziato) e chiama
Director
facendo riferimento a esso.
Questo chiarisce che questo modello non è così per costruire le parti e assemblare il tutto (che dopotutto non è altro che un aiuto per semplificare la fornitura di tutti gli elementi contemporaneamente), ma più per restituire "rappresentazioni" molto diverse ( classi) utilizzando la stessa procedura per la costruzione delle parti.
Uso reale del modello completo
L'uso tipico nella vita reale consiste nel costruire oggetti compositi con diversi tipi di implementazione / rappresentazione, come ad esempio diverse rappresentazioni grafiche / viste (es. Entity / Relationship o modello UML), diversi formati di input o output (ad es. documento JSON o XML) o codifiche (es. ASCII vs UTF16 / 32).
Ad esempio, un uso concreto potrebbe essere ADO.net con DbCommandBuilder
implementato da calcestruzzo SqlCommandBuilder
, OracleCommandBuilder
, ODBCCommandBuilder
per generare comandi specifici di db.