Qual è la differenza tra il modello Builder Design e il modello Factory Design?


663

Qual è la differenza tra il modello di progettazione Builder e il modello di progettazione Factory?

Quale è più vantaggioso e perché?

Come posso rappresentare i miei risultati come grafico se voglio testare e confrontare / confrontare questi schemi?


13
Dal momento che fanno cose diverse, cosa intendi con "vantaggioso"?
S.Lott

5
Builder è una versione più complessa del costruttore , mentre il metodo factory è semplificato.
Dávid Horváth,

@ DávidHorváth Non descriverei un costruttore come "più complesso". Quando hai a che fare con un costruttore che ha 100 parametri, e ti preoccupi solo di 3 di questi, e sai che il numero di parametri potrebbe cambiare in futuro, l'uso del modello Builder renderebbe la vita di tutti molto più semplice.
Aberrant,

@Aberrant L'uso complicato e la complessità architettonica sono due cose diverse. Mi sono concentrato su quest'ultimo.
Dávid Horváth,

Risposte:


466

Con i modelli di progettazione, di solito non esiste una soluzione "più vantaggiosa" che funzioni in tutti i casi. Dipende da cosa devi implementare.

Da Wikipedia:

  • Builder si concentra sulla costruzione di un oggetto complesso passo dopo passo. Abstract Factory enfatizza una famiglia di oggetti prodotto (semplici o complessi). Il costruttore restituisce il prodotto come passaggio finale, ma per quanto riguarda la Fabbrica astratta, il prodotto viene restituito immediatamente.
  • Il costruttore spesso crea un composito.
  • Spesso, i progetti iniziano con il metodo Factory (meno complicati, più personalizzabili, le sottoclassi proliferano) e si evolvono verso Abstract Factory, Prototype o Builder (più flessibile, più complesso) man mano che il progettista scopre dove è necessaria maggiore flessibilità.
  • A volte i modelli di creazione sono complementari: Builder può utilizzare uno degli altri modelli per implementare quali componenti vengono creati. Abstract Factory, Builder e Prototype possono utilizzare Singleton nelle loro implementazioni.

Voce di Wikipedia per il modello di progettazione della fabbrica: http://en.wikipedia.org/wiki/Factory_method_pattern

Voce di Wikipedia per il modello di progettazione del costruttore: http://en.wikipedia.org/wiki/Builder_pattern


159
Questa è esattamente la differenza. Il generatore è necessario solo quando un oggetto non può essere prodotto in un solo passaggio. Un grande esempio di questo potrebbe essere il processo di deserializzazione di un oggetto complesso. Spesso i parametri per l'oggetto complesso devono essere recuperati uno per uno.
Bernard Igiri,

1
Per la prima frase, direi che spesso esiste una soluzione più vantaggiosa che si applica in senso lato ... semplicemente non li vediamo, perché finiscono direttamente nei linguaggi di programmazione.
Joel Coehoorn,

4
@Joel: sono d'accordo sul fatto che alcuni modelli sono più comuni di altri (ad esempio, Factory sembra essere più comune di Builder), ma ciò che intendevo dire è che nessuno di essi è sempre migliore dell'altro, indipendentemente dallo scenario .
Adrian Grigore,

@AdrianGrigore cosa succede se mescoli entrambi ?? aso.net mvc ha ControllerBuilder che ha impostato e ottiene il metodo per la classe ControllerFactory
AminM

Goood risponde, anche se 2 cose che vale la pena aggiungere sono: 1) Builder è principalmente usato per costruire POJO usando l'API Fluent (es. Person.builder (). WithName ("Sam"). WithAge (38) .build (). 2) Nella mia esperienza, builder è utile per la creazione di POJO per oggetti di dominio, mentre factory è utile per creare oggetti di servizio come la classe PdfGeneratorFactory. L'oggetto servizio può essere memorizzato nella cache all'interno della fabbrica per più di 1 volta, mentre il builder crea sempre un nuovo oggetto in base alla progettazione.
saurabh. In

359

Una fabbrica è semplicemente una funzione wrapper attorno a un costruttore (possibilmente uno in una classe diversa). La differenza fondamentale è che un modello di metodo di fabbrica richiede che l'intero oggetto venga creato in una singola chiamata di metodo, con tutti i parametri passati su una sola riga. L'oggetto finale verrà restituito.

Un modello builder , d'altra parte, è essenzialmente un oggetto wrapper attorno a tutti i possibili parametri che potresti voler passare in una chiamata del costruttore. Ciò consente di utilizzare i metodi setter per costruire lentamente l'elenco dei parametri. Un metodo aggiuntivo su una classe builder è un metodo build (), che passa semplicemente l'oggetto builder nel costruttore desiderato e restituisce il risultato.

In linguaggi statici come Java, questo diventa più importante quando si hanno più di una manciata di parametri (potenzialmente opzionali), in quanto si evita la necessità di avere costruttori telescopici per tutte le possibili combinazioni di parametri. Inoltre, un builder consente di utilizzare i metodi setter per definire i campi di sola lettura o privati ​​che non possono essere modificati direttamente dopo che il costruttore è stato chiamato.

Esempio di fabbrica di base

// Factory
static class FruitFactory {
    static Fruit create(name, color, firmness) {
        // Additional logic
        return new Fruit(name, color, firmness);
    }
}

// Usage
Fruit fruit = FruitFactory.create("apple", "red", "crunchy");

Esempio di generatore di base

// Builder
class FruitBuilder {
    String name, color, firmness;
    FruitBuilder setName(name)         { this.name     = name;     return this; }
    FruitBuilder setColor(color)       { this.color    = color;    return this; }
    FruitBuilder setFirmness(firmness) { this.firmness = firmness; return this; }
    Fruit build() {
        return new Fruit(this); // Pass in the builder
    }
}

// Usage
Fruit fruit = new FruitBuilder()
        .setName("apple")
        .setColor("red")
        .setFirmness("crunchy")
        .build();

Potrebbe valere la pena confrontare gli esempi di codice di queste due pagine di Wikipedia:

http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Builder_pattern


1
Quello non è l'uso corretto di imo pattern builder, anche nel collegamento wiki che hai usato è diverso. Questo FruitBuilder è una combinazione di componenti Director e Builder in cui si richiama build () che dovrebbe appartenere a Director e setter che appartengono al componente Builder. Director dovrebbe contenere la logica aziendale su come creare un oggetto usando i metodi Builders. Le apis fluide non sono schemi di costruzione e StringBuilder non è neppure schema di costruzione.
Kmaczek,

282

Il modello Factory può quasi essere visto come una versione semplificata del modello Builder.

Nel modello Factory , la fabbrica è responsabile della creazione di vari sottotipi di un oggetto a seconda delle esigenze.

L'utente di un metodo factory non deve conoscere il sottotipo esatto di quell'oggetto. Un esempio di un metodo factory createCarpotrebbe restituire uno Fordo un Hondaoggetto digitato.

Nel modello Builder , anche diversi sottotipi vengono creati con un metodo builder, ma la composizione degli oggetti potrebbe differire all'interno della stessa sottoclasse.

Per continuare l'esempio dell'auto potresti avere un createCarmetodo di costruzione che crea un Hondaoggetto a forma di con un motore a 4 cilindri o un Hondaoggetto a forma di con 6 cilindri. Il modello del costruttore consente questa granularità più fine.

I diagrammi sia del modello Builder che del modello del metodo Factory sono disponibili su Wikipedia.


13
Il modello del costruttore è come ingrandire la costruzione del grande oggetto. Il grande oggetto è composto da un altro oggetto che è composto ulteriormente come una ricorsione. Mentre la fabbrica ti darà la cosa in una sola chiamata. Questa comprensione è corretta?
Fooo,

63

Il modello di progettazione del builder descrive un oggetto che sa come creare un altro oggetto di un tipo specifico in più passaggi. Contiene lo stato necessario per l'oggetto di destinazione in ogni passaggio intermedio. Pensa a cosa passa StringBuilder per produrre una stringa finale.

Il modello di progettazione di fabbrica descrive un oggetto che sa come creare diversi tipi di oggetti diversi ma correlati in un unico passaggio, in cui il tipo specifico viene scelto in base a determinati parametri. Pensa al sistema di serializzazione, in cui crei il serializzatore e costruisce l'oggetto desiderato tutto in una chiamata di caricamento.


7
Qualche suggerimento: un buon esempio per lo schema del builder è "interfaccia fluente" e ADO.NET è pieno di implementazioni "factory" e "abstract factory" (es. DbFactory).
Boj,

50
  • Costruire passo dopo passo un oggetto complesso: modello di generatore

  • Un oggetto semplice viene creato utilizzando un solo metodo: modello di metodo di fabbrica

  • Creazione di un oggetto utilizzando più metodi di fabbrica: modello di fabbrica astratto


21

Builder Pattern e Factory pattern, entrambi sembrano abbastanza simili agli occhi nudi perché entrambi creano oggetti per te.

Ma devi guardare più da vicino

Questo esempio di vita reale renderà più chiara la differenza tra i due.

Supponiamo che tu sia andato in un fast food e hai ordinato cibo .

1) Quale cibo?

Pizza

2) Quali condimenti?

Capsico, Pomodoro, Pollo BBQ, SENZA ANANAS

Quindi diversi tipi di alimenti sono prodotti dal modello Factory, ma le diverse varianti (sapori) di un particolare alimento sono realizzate dal modello Builder.

Diversi tipi di alimenti

Pizza, Burger, Pasta

Varianti di Pizza

Solo formaggio, formaggio + pomodoro + peperone, formaggio + pomodoro ecc.

Esempio di codice

Puoi vedere l'implementazione del codice di esempio di entrambi i pattern qui
Builder Pattern
Factory Pattern


1
Grazie per aver fornito il codice di esempio! I tuoi esempi differenziano molto bene questi 2 schemi.
Rommel Paras,

18

Entrambi sono modelli creazionali, per creare oggetti.

1) Modello di fabbrica - Supponiamo che tu abbia una super classe e un numero N di sottoclassi. L'oggetto creato dipende da quale parametro / valore viene passato.

2) Builder pattern - per creare oggetti complessi.

Ex: Make a Loan Object. Loan could be house loan, car loan ,
    education loan ..etc. Each loan will have different interest rate, amount ,  
    duration ...etc. Finally a complex object created through step by step process.

12

Innanzitutto alcune cose generali che seguono il mio argomento:

La sfida principale nella progettazione di grandi sistemi software è che devono essere flessibili e semplici da cambiare. Per questo motivo, ci sono alcune metriche come accoppiamento e coesione. Per ottenere sistemi che possono essere facilmente modificati o estesi nella sua funzionalità senza la necessità di riprogettare l'intero sistema da zero, è possibile seguire i principi di progettazione (come SOLID, ecc.). Dopo un po 'alcuni sviluppatori hanno riconosciuto che se seguono questi principi ci sono alcune soluzioni simili che hanno funzionato bene con problemi simili. Queste soluzioni standard si sono rivelate i modelli di progettazione.

Quindi i modelli di progettazione sono di supporto per seguire i principi generali di progettazione al fine di ottenere sistemi debolmente accoppiati con elevata coesione.

Rispondere alla domanda:

Chiedendo la differenza tra due modelli, devi chiederti quale modello rende il tuo sistema più flessibile. Ogni modello ha il suo scopo di organizzare le dipendenze tra le classi nel tuo sistema.

The Abstract Factory Pattern: GoF: "Fornisci un'interfaccia per la creazione di famiglie di oggetti correlati o dipendenti senza specificare le loro classi concrete".

Cosa significa: Fornendo un'interfaccia come questa, la chiamata al costruttore di ciascun prodotto della famiglia viene incapsulata nella classe di fabbrica. E poiché questo è l'unico posto nell'intero sistema in cui vengono chiamati quei costruttori, puoi modificare il tuo sistema implementando una nuova classe di fabbrica. Se si scambia la rappresentazione della fabbrica con un'altra, è possibile scambiare un intero set di prodotti senza toccare la maggior parte del codice.

The Builder Pattern: GoF: "Separare la costruzione di un oggetto complesso dalla sua rappresentazione in modo che lo stesso processo di costruzione possa creare rappresentazioni diverse."

Cosa significa: incapsuli il processo di costruzione in un'altra classe, chiamata direttore (GoF). Questo direttore contiene l'algoritmo di creazione di nuove istanze del prodotto (ad es. Comporre un prodotto complesso da altre parti). Per creare le parti integrali dell'intero prodotto, il regista utilizza un costruttore. Scambiando il costruttore nel regista è possibile utilizzare lo stesso algoritmo per creare il prodotto, ma modificare le rappresentazioni delle singole parti (e quindi la rappresentazione del prodotto). Per estendere o modificare il sistema nella rappresentazione del prodotto, è sufficiente implementare una nuova classe builder.

In breve: lo scopo di Abstract Factory Pattern è quello di scambiare una serie di prodotti che sono fatti per essere usati insieme. Lo scopo del Builder Pattern è incapsulare l'algoritmo astratto di creazione di un prodotto per riutilizzarlo per diverse rappresentazioni del prodotto.

Secondo me non si può dire che il modello astratto di fabbrica sia il fratello maggiore del modello costruttore. SÌ, sono entrambi schemi di creazione, ma l'intento principale degli schemi è completamente diverso.


bella risposta, spiegazione elaborata.
travagliato

puoi per favore spiegare il significato di "Separare la costruzione di un oggetto complesso dalla sua rappresentazione"
Rajdeep

@Rajdeep la spiegazione è desiderare un commento, ecco perché ho scritto un'altra risposta.
Janis

@Janis Dov'è quella risposta o fonte da cui posso leggere?
Rajdeep,

@Rajdeep ti consiglio di leggere il libro "Design Patterns" - amazon.de/Patterns-Elements-Reusable-Object-Oriented-Software/…
Janis

7

Una notevole differenza tra costruttore e fabbrica che ho potuto capire era la seguente

supponiamo di avere una macchina

class Car
{
  bool HasGPS;
  bool IsCityCar;
  bool IsSportsCar;
  int   Cylenders;
  int Seats;

  public:
     void Car(bool hasGPs=false,bool IsCityCar=false,bool IsSportsCar=false, int Cylender=2, int Seats=4);
 };

Nell'interfaccia sopra possiamo ottenere l'auto nel modo seguente:

 int main()
 {
    BadCar = new Car(false,false,true,4,4);
  }

ma cosa succede se si verificano delle eccezioni durante la creazione dei posti ??? NON RICEVERAI L'OGGETTO // MA MA

supponiamo di avere un'implementazione come la seguente

class Car
 {
    bool mHasGPS;
    bool mIsCityCar;
    bool mIsSportsCar;
    int mCylenders;
    int mSeats;

 public:
    void Car() : mHasGPs(false), mIsCityCar(false), mIsSportsCar(false), mCylender(2), mSeats(4) {}
    void SetGPS(bool hasGPs=false)  {mHasGPs = hasGPs;}
    void SetCity(bool CityCar)  {mIsCityCar = CityCar;}
    void SetSports(bool SportsCar)  {mIsSportsCar = SportsCar;}
    void SetCylender(int Cylender)  {mCylenders = Cylender;}    
    void SetSeats(int seat) {mSeats = seat;}    
};

 class CarBuilder 
 {
    Car* mCar;
public:
        CarBuilder():mCar(NULL) {   mCar* = new Car();  }
        ~CarBuilder()   {   if(mCar)    {   delete mCar;    }
        Car* GetCar()   {   return mCar; mCar=new Car();    }
        CarBuilder* SetSeats(int n) {   mCar->SetSeats(n); return this; }
        CarBuilder* SetCylender(int n)  {   mCar->SetCylender(n); return this;  }
        CarBuilder* SetSports(bool val) {   mCar->SetSports(val); return this;  }
        CarBuilder* SetCity(bool val)   {   mCar->SetCity(val); return this;    }
        CarBuilder* SetGPS(bool val)    {   mCar->SetGPS(val); return this; }
}

Ora puoi creare così

 int main()
 {
   CarBuilder* bp =new CarBuilder;
    Car* NewCar  = bp->SetSeats(4)->SetSports(4)->SetCity(ture)->SetGPS(false)->SetSports(true)->GetCar();

     bp->SetSeats(2);

     bp->SetSports(4);

     bp->SetCity(ture);

     bp->SetSports(true)

     Car* Car_II=  bp->GetCar();

  }

Qui nel secondo caso, anche se un'operazione fallisce, otterresti comunque l'auto.

Potrebbe essere che l'auto non funzioni perfettamente più tardi ma, avresti l'oggetto.

Perché il metodo Factory ti dà l'auto in una sola chiamata, mentre il costruttore costruisce uno per uno.

Tuttavia, dipende dalle esigenze del degnato di chi scegliere.


2
Sicuramente è meglio non avere affatto un'auto che un'auto non valida: cosa succede se si trova il problema solo quando si utilizzano le pause?
Ken

@Ken: Non sto insistendo sul fatto che sia un buon design dal punto di vista del progetto commerciale, ecc. Piuttosto, l'intenzione di citare questo esempio per esemplificare la differenza tra i modelli. Sicuramente, hai ragione a dire che questo è negativo per l'esperienza dell'utente che ha danneggiato la macchina, ma, considera, c'è un impianto in cui vengono costruite le auto e alcune parti non funzionano correttamente, quindi l'auto viene prodotta ma con una brutta pausa che si potrebbe scoprire in il tempo di prova e spedizione di quell'auto al cliente è fermo.
Fooo,

2
Vorrei chiarire che in realtà sono un grande fan del modello del costruttore, tuttavia, non per il motivo che hai indicato. Un oggetto che non è valido dovrebbe fallire durante la costruzione, più in basso viene trovato un bug, più costoso è. Con il modello builder sarebbe normale che il metodo build (nel tuo esempio chiamato getCar ()) generasse un'eccezione se mancano dei dati richiesti.
Ken,

7
+-------------------------------------------------------------------+---------------------------------------------------+
|                              Builder                              |                      Factory                      |
+-------------------------------------------------------------------+---------------------------------------------------+
| Return only single instance to handle complex object construction | Retrun various instances on multiple constructors |
| No interface required                                             | Interface driven                                  |
| Inner classes is involved (to avoid telescopic constructors)      | Subclasses are involved                           |
+-------------------------------------------------------------------+---------------------------------------------------+  

Modello di costruzione telescopica

Analogia:

  • Fabbrica: considera un ristorante. La creazione del "pasto di oggi" è un modello di fabbrica, perché dici alla cucina "prendimi il pasto di oggi" e la cucina (fabbrica) decide quale oggetto generare, in base a criteri nascosti.
  • Builder: il builder appare se ordini una pizza personalizzata. In questo caso, il cameriere dice allo chef (costruttore) "Ho bisogno di una pizza; aggiungi formaggio, cipolle e pancetta!" Pertanto, il builder espone gli attributi che l'oggetto generato dovrebbe avere, ma nasconde come impostarli.

Cortesia


5

Builder e Abstract Factory hanno significato per scopi diversi. A seconda del caso d'uso corretto, è necessario selezionare un modello di progettazione adatto.

Caratteristiche salienti del costruttore :

  1. Il modello Builder crea un oggetto complesso utilizzando oggetti semplici e utilizzando un approccio graduale
  2. Una classe Builder crea l'oggetto finale passo dopo passo. Questo builder è indipendente da altri oggetti
  3. Sostituzione al metodo Factory / Fabbrica astratta in questo scenario: Troppi argomenti per passare dal programma client alla classe Factory che possono essere soggetti a errori
  4. Alcuni dei parametri potrebbero essere opzionali a differenza di Factory che forza a inviare tutti i parametri

Caratteristiche salienti di Factory (semplice Factory):

  1. Modello creazionale
  2. Basato sull'eredità
  3. Factory restituisce un metodo Factory (interfaccia) che a sua volta restituisce Concrete Object
  4. È possibile sostituire nuovi oggetti concreti con l'interfaccia e il client (chiamante) non deve essere a conoscenza di tutte le implementazioni concrete
  5. Il client accede sempre solo all'interfaccia e puoi nascondere i dettagli di creazione dell'oggetto nel metodo Factory.

Spesso i progetti iniziano con il metodo Factory (meno complicati, più personalizzabili, le sottoclassi proliferano) e si evolvono verso Abstract Factory , Prototype o Builder (più flessibile, più complesso)

Dai un'occhiata ai post correlati:

Mantenere il costruttore in una classe separata (interfaccia fluida)

Modelli di progettazione: metodo Factory vs Factory vs Factory astratto

Puoi fare riferimento agli articoli seguenti per maggiori dettagli:

sourcemaking

journaldev


5

Factory : utilizzato per creare un'istanza di un oggetto in cui le dipendenze dell'oggetto sono interamente gestite dalla factory. Per il modello di fabbrica astratta , ci sono spesso molte implementazioni concrete della stessa fabbrica astratta. La corretta implementazione della fabbrica viene iniettata tramite iniezione di dipendenza.

Builder : utilizzato per costruire oggetti immutabili , quando le dipendenze dell'oggetto da istanziare sono in parte note in anticipo e in parte fornite dal client del builder.


4

Gli schemi Factory & Builder astratti sono entrambi schemi Creazionali ma con intenti diversi.

Abstract Factory Pattern enfatizza la creazione di oggetti per famiglie di oggetti correlati in cui:

  • Ogni famiglia è un insieme di classi derivate da una classe / interfaccia di base comune.
  • Ogni oggetto viene restituito immediatamente a seguito di una chiamata.

Il modello Builder si concentra sulla costruzione passo dopo passo di un oggetto complesso. Disaccoppia la rappresentazione dal processo di costruzione dell'oggetto complesso, in modo che lo stesso processo di costruzione possa essere utilizzato per rappresentazioni diverse.

  • L'oggetto Builder incapsula la configurazione dell'oggetto complesso.
  • L'oggetto Director conosce il protocollo di utilizzo di Builder, in cui il protocollo definisce tutti i passaggi logici necessari per creare l'oggetto complesso.

puoi per favore spiegare il significato di "disaccoppia la rappresentazione dal processo di costruzione dell'oggetto complesso"
Rajdeep

3

Una costruzione complessa è quando l'oggetto da costruire è composto da diversi altri oggetti che sono rappresentati da astrazioni.

Prendi in considerazione un menu in McDonald's. Un menu contiene un drink, un piatto principale e un lato. A seconda di quali discendenti delle singole astrazioni sono composte insieme, il menu creato ha un'altra rappresentazione.

  1. Esempio: Cola, Big Mac, patatine fritte
  2. Esempio: Sprite, Nuggets, Patatine Fritte

Lì abbiamo ottenuto due istanze del menu con diverse rappresentazioni. Il processo di costruzione a sua volta rimane lo stesso. Si crea un menu con un drink, una principale e una laterale.

Utilizzando il modello builder, si separa l'algoritmo di creazione di un oggetto complesso dai diversi componenti utilizzati per crearlo.

In termini di modello di generatore, l'algoritmo è incapsulato nel direttore mentre i costruttori vengono utilizzati per creare le parti integrali. Variando il costruttore usato nell'algoritmo del regista si ottiene una rappresentazione diversa perché altre parti sono composte da un menu. Il modo in cui viene creato un menu rimane lo stesso.


1
Questo spiega la "separazione della costruzione di un oggetto complesso dalla sua rappresentazione"
Rajdeep,

2

La principale differenza tra loro è che il modello Builder descrive principalmente la creazione di oggetti complessi passo dopo passo. Nel modello di Fabbrica astratta, l'enfasi è posta sulle famiglie di oggetti-prodotti . Il costruttore restituisce il prodotto nell'ultimo passaggio . Mentre nel modello Abstract Factory il prodotto è immediatamente disponibile .

Esempio: supponiamo che stiamo creando Maze

1. Fabbrica astratta:

Maze* MazeGame::CreateMaze (MazeFactory& factory) {
Maze* maze = factory.MakeMaze(); /// product is available at start!!
 /* Call some methods on maze */
return maze;
}

2. Costruttore:

Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.buildMaze(); /// We don't have access to maze
 /* Call some methods on builder */
return builder.GetMaze();
}

2

Credo che l'utilizzo e la differenza tra i modelli Factory & Builder possano essere compresi / chiariti più facilmente in un determinato periodo di tempo mentre lavoravi sulla stessa base di codice e cambiando i requisiti.

Dalla mia esperienza, di solito, inizi con un modello Factory che include un paio di metodi creatori statici per nascondere principalmente una logica di inizializzazione relativamente complessa. Man mano che la gerarchia degli oggetti diventa più complessa (o quando aggiungi più tipi, parametri), probabilmente finisci per avere i tuoi metodi popolati con più parametri e per non parlare del fatto che dovrai ricompilare il modulo Factory. Tutta questa roba, aumenta la complessità dei metodi del tuo creatore, diminuisce la leggibilità e rende il modulo di creazione più fragile.

Questo punto probabilmente sarà il punto di transizione / estensione. In questo modo, si crea un modulo wrapper attorno ai parametri di costruzione e quindi sarai in grado di rappresentare nuovi oggetti (simili) aggiungendo altre astrazioni (forse) e implementazioni senza toccare la logica della tua creazione. Quindi hai avuto una logica "meno" complessa.

Francamente, fare riferimento a qualcosa di "avere un oggetto creato in uno o più passaggi è la differenza" in quanto l'unico fattore di diversità non era sufficiente per distinguerli dal momento che potevo usare entrambi i modi per quasi tutti i casi che ho affrontato ora senza sperimentare alcun beneficio. Quindi questo è quello che ho finalmente pensato.


2

Il vantaggio principale del modello del costruttore rispetto al modello di fabbrica è nel caso in cui si desideri creare un oggetto standard con molte possibili personalizzazioni, ma di solito si finisce per personalizzare solo alcune.

Ad esempio, se si desidera scrivere un client HTTP, verranno impostati alcuni parametri predefiniti come timeout di scrittura / lettura predefiniti, protocolli, cache, DNS, intercettori, ecc.

La maggior parte degli utenti del tuo client utilizzerà solo quei parametri predefiniti, mentre alcuni altri utenti potrebbero voler personalizzare alcuni degli altri parametri. In alcuni casi, ti consigliamo di modificare i timeout e utilizzare il resto così com'è, mentre in altri casi potresti dover personalizzare, ad esempio, la cache.

Ecco i modi possibili per creare un'istanza del client (tratto da OkHttpClient):

//just give me the default stuff
HttpClient.Builder().build()   

//I want to use custom cache
HttpClient.Builder().cache(MyCache()).build() 

//I want custom connection timeout
HttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).build() 

//I am more interested in read/write timeout
HttpClient.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS).build()

Se utilizzi un modello di fabbrica per questo, finirai per scrivere molti metodi con tutte le possibili combinazioni di parametri di creazione. Con il builder, devi solo specificare quelli a cui tieni e lasciare che il builder lo costruisca per te prendendoti cura di tutti quegli altri parametri.


1

Il modello di costruzione enfatizza la complessità della creazione di oggetti (risolto da "passaggi")

Il modello astratto enfatizza "solo" l '"astrazione" di oggetti (multipli ma correlati).


1

La differenza è chiara Nel modello del builder, il builder creerà per te un tipo specifico di oggetto. Devi dire cosa deve costruire il costruttore. Nel modello di fabbrica, usando la classe astratta stai costruendo direttamente l'oggetto specifico.

Qui la classe builder funge da mediatore tra la classe principale e le classi di tipo specifico. Più astrazione.


1

Entrambi sono molto simili, ma se si dispone di un gran numero di parametri per la creazione di oggetti con alcuni opzionali con alcuni valori predefiniti, selezionare Builder pattern.


1

A parer mio

Il costruttore è una specie di fabbrica più complessa.

Ma in Builder puoi istanziare oggetti usando altre fabbriche , necessarie per costruire un oggetto finale e valido.

Quindi, parlando dell'evoluzione dei "Modelli Creazionali" per complessità, puoi pensarci in questo modo:

Dependency Injection Container -> Service Locator -> Builder -> Factory

1

Entrambi i modelli derivano per la stessa necessità: nascondere da un codice client la logica di costruzione di un oggetto complesso. Ma cosa rende un oggetto "complesso" (o, a volte, complicato)? Principalmente, è dovuto a dipendenze, o meglio allo stato di un oggetto composto da stati più parziali. È possibile iniettare dipendenze dal costruttore per impostare lo stato dell'oggetto iniziale, ma un oggetto potrebbe richiederne molti, alcuni saranno in uno stato iniziale predefinito (solo perché avremmo dovuto imparare che impostare una dipendenza predefinita su null non è il modo più pulito ) e alcuni altri impostati su uno stato guidato da una condizione. Inoltre, ci sono proprietà dell'oggetto che sono una sorta di "dipendenze ignare", ma possono anche assumere stati opzionali.

ci sono due modi ben noti per dominare quella complessità:

  • Composizione / aggregazione: costruisci un oggetto, costruisci i suoi oggetti dipendenti, quindi lega insieme. Qui, un builder può rendere trasparente e flessibile il processo che determina le regole che guidano la costruzione del componente.

  • Polimorfismo: le regole di costruzione vengono dichiarate direttamente nella definizione del sottotipo, quindi si dispone di un insieme di regole per ciascun sottotipo e una condizione decide quale tra queste serie di regole si applica per costruire l'oggetto. Una fabbrica si adatta perfettamente a questo scenario.

Nulla impedisce di mescolare questi due approcci. Una famiglia di prodotti potrebbe astrarre la creazione di oggetti eseguita con un builder, un builder potrebbe usare le fabbriche per determinare quale oggetto componente viene istanziato.


0

A mio avviso, il modello Builder viene utilizzato quando si desidera creare un oggetto da un gruppo di altri oggetti e la creazione di una parte deve essere indipendente dall'oggetto che si desidera creare. Aiuta a nascondere la creazione della parte dal client per rendere indipendente il costruttore e il client. Viene utilizzato per la creazione di oggetti complessi (oggetti che possono consistere in proprietà complicate)

Mentre il modello di fabbrica specifica che si desidera creare oggetti di una famiglia comune e che si desidera che venga cerato contemporaneamente. È usato per oggetti più semplici.


0

Costruttore e fabbrica astratta

Il modello di progettazione del generatore è molto simile, in una certa misura, al modello di Fabbrica astratta. Ecco perché è importante essere in grado di fare la differenza tra le situazioni quando viene utilizzata l'una o l'altra. Nel caso della Fabbrica astratta, il cliente utilizza i metodi della fabbrica per creare i propri oggetti. Nel caso del Builder, la classe Builder viene istruita su come creare l'oggetto e quindi viene chiesta, ma il modo in cui la classe viene messa insieme dipende dalla classe Builder, questo dettaglio fa la differenza tra i due modelli.

Interfaccia comune per i prodotti

In pratica i prodotti creati dai costruttori di calcestruzzo hanno una struttura significativamente diversa, quindi se non vi è motivo di ricavare prodotti diversi una classe genitore comune. Ciò distingue anche il modello Builder dal modello Fabbrica astratta che crea oggetti derivati ​​da un tipo comune.

Da: http://www.oodesign.com/builder-pattern.html


-2

Il modello di fabbrica crea un'implementazione concreta di una classe in fase di esecuzione, ovvero l'intenzione principale è quella di utilizzare il polimorfismo per consentire alle sottoclassi di decidere quale classe creare un'istanza. Ciò significa che al momento della compilazione non conosciamo la classe esatta che verrà creata, mentre il modello Builder si occupa principalmente di risolvere il problema dei telescopi antropomorfi, che sorge a causa di un gran numero di campi opzionali di una classe. Nel modello del costruttore non esiste alcuna nozione di polimorfismo, poiché sappiamo quale oggetto stiamo cercando di costruire al momento della compilazione.

L'unico tema comune di questi due modelli è il nascondimento di costruttori e la creazione di oggetti dietro i metodi di fabbrica e il metodo di costruzione, per migliorare la costruzione degli oggetti.


-2

Il modello di fabbrica ti consente di creare un oggetto contemporaneamente, mentre il modello di generatore ti consente di interrompere il processo di creazione di un oggetto. In questo modo, è possibile aggiungere diverse funzionalità durante la creazione di un oggetto.

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.