"StringBuilder" è un'applicazione del Builder Design Pattern?


31

Il modello "Costruttore" è limitato all'anti-modello del "costruttore telescopico" o si può dire che affronti anche il problema più generale della creazione complicata di oggetti immutabili?

La StringBuilderclasse ha la parola "costruttore" nel suo nome, ma non ha nulla a che fare con i costruttori telescopici, ci aiuta semplicemente a raccogliere tutti i dati di cui abbiamo bisogno per passare al costruttore di un oggetto immutabile.

A me sembra che la risposta sia un "sì" molto chiaro, ma sembra esserci un disaccordo sull'argomento, quindi speravo che qualcuno potesse forse chiarirlo.

Stavo rispondendo a questa domanda: Programmatori SE: legittimo “vero lavoro” in un costruttore? dove l'OP vuole creare un oggetto (presumibilmente immutabile) contenente un albero complesso, e l'idea del modello "builder" è spuntata, e durante la ricerca ho trovato questo Q&A che sembra dire che lo stile di creazione dell'oggetto "StringBuilder" è non un'applicazione del modello "Builder", per motivi che non mi sono chiari: Stackoverflow - StringBuilder e Builder Pattern . (Coloro che hanno risposto a questa domanda non sono riusciti a esprimere un punto convincente per quanto ne so.)


2
Trovo la risposta di Paul Sasik su quella domanda Stack Overflow del tutto convincente: StringBuilder è una "soluzione" per il problema prestazionale di concatenare stringhe immutabili, niente di più. Nella migliore delle ipotesi, StringBuilder è "purtroppo chiamato". Potresti sostenere che StringBuilder può "costruire" pagine Web, suppongo, ma si tratta di un'applicazione specifica di un meccanismo generale.
Robert Harvey,

3
La risposta di Paul Sasik è errata per Java: ho esaminato il codice sorgente sottostante. StringBuildersembra utilizzare una matrice di caratteri sottostante per rappresentare la stringa e consente di eseguire operazioni come inserimenti e rimozioni in qualsiasi momento. In definitiva, penso che StringBuilder sia una soluzione alternativa per oggetti String immutabili, ma per il resto mi sembra che soddisfi l'intento del modello Builder.
Thomas Owens

4
Devo pensarci molto di più - mi dà fastidio. Ho quasi iniziato a scrivere perché qualcosa come StringBuilder è una versione del modello Builder e tutti gli altri si sbagliavano. Ma ho trovato alcuni punti deboli, mi sono convinto che mi sbagliavo, ma poi sono riuscito a tornare al mio primo pensiero. Se guardi solo l'intento del modello Builder, è facile vedere che "StringBuilder è un Builder". Se guardi la struttura del modello Builder, è più difficile.
Thomas Owens

1
Per quello che vale, questa risposta su Stack Overflow concorda con il mio pensiero iniziale che StringBuilder è un'implementazione del builder e i commenti sono interessanti. Quindi puoi trovare entrambi i lati dell'argomento. Sono favorevole a questa domanda: non so se posso costruire una buona risposta, ma è sicuramente una domanda interessante. Ci penserò.
Thomas Owens

2
Non tutti i modelli GoF resistono alla prova del tempo. Non sto dicendo , sto solo dicendo.
Ben

Risposte:


36

A StringBuilderè simile al modello Builder, ma non condivide molto con la descrizione GoF di questo modello di progettazione. Il punto originale del modello progettuale era

Separare la costruzione di un oggetto complesso dalla sua rappresentazione in modo che lo stesso processo di costruzione possa creare rappresentazioni diverse.

- da Design Patterns , di Gamma, Helm, Johnson, Vlissides.

(nota: "complesso" significa principalmente "composto da più parti", non necessariamente "complicato" o "difficile")

Le "diverse rappresentazioni" è la chiave qui. Ad esempio, assumendo questo processo di costruzione:

interface ArticleBuilder {
  void addTitle(String title);
  void addParagraph(String paragraph);
}

void createArticle(ArticeBuilder articleBuilder) {
  articleBuilder.addTitle("Is String Builder an application of ...");
  articleBuilder.addParagraph("Is the Builder Pattern restricted...");
  articleBuilder.addParagraph("The StringBuilder class ...");
}

potremmo finire con una HtmlDocumento una TexDocumento una a MarkdownDocumentseconda di quale implementazione concreta è fornita:

class HtmlDocumentBuilder implements ArticleBuilder {
  ...
  HtmlDocument getResult();
}

HtmlDocumentBuilder b = new HtmlDocumentBuilder();
createArticle(b);
HtmlDocument dom = b.getResult();

Quindi un punto centrale del modello del costruttore è il polimorfismo . Il libro Design Patterns confronta questo modello con la Fabbrica astratta:

La Fabbrica astratta è simile al Costruttore in quanto anch'essa può costruire oggetti complessi. La differenza principale è che il modello Builder si concentra sulla costruzione passo dopo passo di un oggetto complesso. […] Il costruttore restituisce il prodotto come passaggio finale, ma per quanto riguarda la Fabbrica astratta, il prodotto viene restituito immediatamente.

- da Design Patterns , di Gamma, Helm, Johnson, Vlissides.

Questo aspetto passo dopo passo è diventato quindi l'aspetto più popolare del modello Builder, in modo che nella forma comune il modello Builder sia compreso in questo modo:

Dividi la costruzione di un oggetto in più passaggi. Questo ci consente di utilizzare argomenti denominati o parametri opzionali anche in lingue che non supportano queste funzionalità.

Wikipedia definisce lo schema in questo modo:

Il modello builder è un modello di progettazione software per la creazione di oggetti. A differenza del modello di fabbrica astratto e del modello di metodo di fabbrica la cui intenzione è di abilitare il polimorfismo, l'intenzione del modello di costruttore è quella di trovare una soluzione all'antimetro del costruttore telescopico [citazione necessaria] . [...]

Il modello del costruttore ha un altro vantaggio. Può essere utilizzato per oggetti che contengono dati flat (codice html, query SQL, certificato X.509 ...), vale a dire dati che non possono essere facilmente modificati. Questo tipo di dati non può essere modificato passo dopo passo e deve essere modificato contemporaneamente. Il modo migliore per costruire un tale oggetto è usare una classe builder. [citazione necessaria]

- da Builder Pattern su Wikipedia , da vari collaboratori.

Come possiamo vedere, non esiste una comprensione veramente comune di quale modello si riferisca questo nome, e in alcuni punti definizioni diverse si contraddicono persino a vicenda (ad esempio per quanto riguarda la rilevanza del polimorfismo per i costruttori).

L'unica proprietà comune del StringBuildercon varie interpretazioni del modello è che il prodotto viene creato passo dopo passo anziché in una volta sola. Non soddisfa una lettura rigorosa della definizione GoF del modello di progettazione, ma si noti che i modelli di progettazione sono concetti malleabili intesi a facilitare la comunicazione. Continuerei a chiamare StringBuilderun esempio del Builder Pattern, anche se atipico - il motivo principale di quella struttura in Java è la concatenazione performante in presenza di stringhe immutabili, ma non un interessante design orientato agli oggetti.


7
Mi sembra che la creazione di oggetti immutabili sembra essere uno degli usi più comuni di Builders: penso che questo abbia sostituito l'uso primario come descritto da GoF, quindi concorda sul fatto che questo è sicuramente meglio descritto come un'istanza del modello.
Jules il

Concordi con l'uso nella creazione di grafici immutabili, Un'altra base per i DSL di Builder è davvero utile per creare grafici di grandi dimensioni di dati falsi / ObjectMothers durante i test di integrazione + unità.
StuartLC,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.