Client vs Creator nei metodi Factory e Abstract Factory

0

Questa pagina descrive una differenza importante tra Factory Method e Abstract Factory :

link

La differenza, secondo questa pagina, è che in Factory Method calcola Creator (cioè l'entità che crea nuovi oggetti) e Client (cioè l'entità che usa Creator ) è il stessa classe . Più precisamente, questo modello definisce solo un metodo , quindi il resto della classe è Client . In Abstract Factory tuttavia, Creator e Client sono classi separate . L'unico scopo di Creator è creare oggetti in modo che solo una classe separata possa essere Client .

Questa distinzione è corretta? In tal caso, perché il metodo Creator in Factory Method non può essere inserito in una classe separata? Creerebbe qualche problema? Allo stesso modo, perché la classe Creator in Abstract Factory non può essere della stessa classe di Client ? Questo creerebbe qualche problema?

Aggiornamento:

Proprio come una nota a margine: è SHOCKING anche a me vedere che quando chiedo dei motivi di design ben noti e (quali dovrebbero essere) ben definiti ottengo in realtà risposte contraddittorie. E non è solo questo thread - più e più chiedo alle persone (o ricerca risorse online) sui modelli di progettazione di base, più inizio a pensare che le persone in realtà NON LEANO VERAMENTE anche se li usano quotidianamente e credono li capiscono.

    
posta NPS 15.11.2014 - 11:59
fonte

4 risposte

2

La tua distinzione non è generalmente corretta. Ad esempio, il modello di fabbrica astratto utilizza il modello di metodo di fabbrica. Nel modello di metodo di fabbrica, le classi che utilizzano e forniscono il metodo factory non devono essere della stessa classe.

Una classe Abstract Factory ha come oggetto esclusivo la creazione di oggetti. Se un'istanza di fabbrica astratta fosse un suo cliente, ciò sarebbe una violazione del principio di Responsabilità Unica.

Di seguito, troverai una discussione sui metodi di fabbrica, il modello di metodo di fabbrica, il modello di fabbrica astratto e confronti tra loro e altri modelli.

Fabbriche o Fabbriche semplici o Metodi di fabbrica

Una factory è una funzione utilizzata per creare una struttura dati. Nei linguaggi OOP, i costruttori sono spesso metodi di fabbrica speciali che non possono essere utilizzati liberamente (ad esempio, spesso non si può esplicitamente return qualcosa). Incorporando la costruzione in un metodo ordinario, possiamo aggiungere il codice di validazione, pre-elaborazione o ulteriore inizializzazione e possiamo restituire oggetti di tipi diversi a seconda del contesto. Usando metodi di fabbrica, gli utenti sono isolati dalle specifiche della costruzione di oggetti - se vogliamo cambiare il tipo di alcuni oggetti, dobbiamo solo cambiare il codice all'interno della fabbrica, e non tutto il codice che usa quel factory.

Le semplici fabbriche non sono un modello di Go4, ma formano la base di molti modelli come il modello di metodo di fabbrica, il modello di fabbrica astratto e il modello di generatore.

Modello metodo di fabbrica

Nel modello di metodo di fabbrica, abbiamo una classe che contiene un metodo di fabbrica sovrascrivibile. Le sottoclassi sono incoraggiate a sovrascrivere questo metodo per modificare il tipo dell'oggetto restituito. Pseudocodice:

interface Product { … }
class DefaultProduct implements Product { … }
class SpiffyProduct  implements Product { … }

class Creator {
  virtual Product create() { return new DefaultProduct() }
}

class OtherCreator extends Creator {
  override Product create() { return new SpiffyProduct() }
}

// client code:
Creator c = ...;
Product = c.create();

Tieni presente che Creator::create è un metodo factory / factory semplice. Tuttavia, la proprietà di identificazione del modello di metodo di fabbrica è l'utilizzo dell'ereditarietà per modificare il metodo di fabbrica.

Il vantaggio del modello di metodo di fabbrica è che per cambiare il metodo di fabbrica utilizzato nel codice cliente, dobbiamo solo cambiare la linea in cui viene ottenuto / creato Creator c . Questa flessibilità consente di utilizzare il modello del metodo di fabbrica per le semplici attività di iniezione delle dipendenze.

Variazioni

Se utilizziamo il metodo del metodo di fabbrica e il client si trova nella stessa classe del metodo di fabbrica, questo può anche essere descritto come il modello di strategia applicato come modello di creazione.

La classe radice Creator non deve essere istanziabile o fornire un prodotto predefinito. Invece, potrebbe essere astratto o un'interfaccia.

Un oggetto può ragionevolmente implementare il modello di metodo di fabbrica più volte per diversi Product s. Se la creazione dell'oggetto è lo scopo principale del creatore e i diversi prodotti sono correlati, questo è probabilmente meglio descritto come il modello astratto di fabbrica.

Generalmente, il Pattern Metodo di Fabbrica viene usato come aiuto per raggiungere la preoccupazione principale di quell'oggetto (per esempio quando usato in combinazione con il Modello di Strategia). Se il metodo factory è l'unico metodo di una classe che implementa il pattern del metodo di fabbrica, questo può anche essere visto come un esempio del pattern di comando.

Modello di fabbrica astratto

Il modello di fabbrica astratto usa il modello di metodo di fabbrica per creare una tavolozza di oggetti correlati. Oppure: l'istanza di fabbrica astratta è quella tavolozza.

Mentre il pattern del metodo di fabbrica viene spesso usato come helper per fare qualcos'altro, la preoccupazione principale di un oggetto factory in Abstract Factory Pattern è sempre la creazione dell'oggetto. Come tale, il client dovrebbe sempre essere una classe diversa, anche se una fabbrica astratta potrebbe anche usarsi da sola, ad es. per assemblare un oggetto composito.

    
risposta data 15.11.2014 - 14:38
fonte
1

Commenti sul testo della domanda

Io minacciato con buone intenzioni che un giorno modificherei il testo della domanda per rimuovere le osservazioni denigratorie. Tali osservazioni non sono tollerate su Programmers.SE. Se hai tempo, modifica il testo della domanda per rimuoverlo, in modo da non doverlo fare. Grazie.

Obiettivo dichiarato

Cercherò di semplificare enormemente la trasformazione graduale di "factory-esque". In tal modo, prometto di evitare la verbosità che ha a lungo tormentato i modelli GoF (e tutti gli aspiranti che cercano di essere esperti di modelli).

Passaggio zero, il metodo di costruzione

  • Il metodo di costruzione crea un oggetto, lo inizializza e restituisce l'oggetto al chiamante.
  • Nella maggior parte delle lingue, il chiamante deve specificare il tipo di foglia (noto anche come "tipo più derivato").
  • Questo requisito di specificità è un grosso limite in vista del polimorfismo - il chiamante non può agire in modo polimorfico (cioè "non può fingere di non sapere la classe") se ha bisogno di chiamare un costruttore , punto.

Passaggio uno, metodo di fabbrica ordinario

  • Un metodo factory normale avvolge il metodo del costruttore.
  • Prende gli argomenti, costruisce l'oggetto esattamente come prima (e lascia che il vero costruttore gestisca l'effettiva inizializzazione, come prima), e lo restituisce.

Ci sono molte differenze.

In primo luogo, rimuove il vincolo di specificità del tipo di foglia dal codice del chiamante. Il codice del chiamante ora non deve conoscere il nome della classe della cosa che sta per creare.

In secondo luogo, un metodo di fabbrica normale è un metodo ordinario . Può essere:

  • Un metodo statico o un metodo di istanza;
  • Un membro della stessa classe o di una classe diversa;
  • O anche un metodo di interfaccia. (Questo sarà discusso di seguito, in Passaggio tre. )

In terzo luogo, e che è ortogonale alle altre differenze, è questo: se l'oggetto to-be-built-and-return appartiene ad una gerarchia di ereditarietà, il metodo ordinario di fabbrica non deve dichiarare il suo tipo di ritorno (il tipo di oggetto che promette di costruire e restituire) per essere il tipo di foglia. Può invece dichiararsi per restituire un tipo di base o un qualche tipo di interfaccia.

Questa terza possibilità conferisce il polimorfismo al tipo di ritorno del metodo factory.

Da questo momento in poi,

Ciascuna possibilità ortogonale di cui sopra può essere mescolata e abbinata per dare origine a molte combinazioni interessanti; alcuni di questi sono coperti dal libro GoF e altri riscoperti da altri guru in epoche successive.

Passaggio due, incapsulamento di più metodi di fabbrica

Qui l'incapsulamento significa semplicemente mettere le cose in una classe.

L'incapsulamento può avere diversi significati.

  • Nascondersi delle informazioni - il solito significato, ma di cui non mi preoccupo ora.
  • Raggruppamento di metodi correlati in un unico luogo (a.k.a. coesione). Questo sarà spiegato qui.

Il metodo factory non deve essere l'unico membro di quella classe. Puoi avere una classe che ha più metodi di fabbrica. Possono avere diverse firme di reso. Possono restituire oggetti che appartengono a gerarchie di ereditarietà non correlate.

Sei tu, il progettista, che decreta che quei due metodi di produzione saranno uniti in uno solo, e quindi li trasformerai in una famiglia.

Naturalmente, un secondo accusatore può venire da te e lamentarsi del fatto che non dovresti mettere due metodi di fabbrica non correlati nella stessa classe. Ma la possibilità è lì; usalo saggiamente.

Passaggio tre, rendendo intercambiabili i metodi di produzione compatibili facendoli membri di un'interfaccia.

Per fare questo devi avere più metodi di fabbrica che condividono due elementi comuni:

  • Gli argomenti (o, la firma) per chiamare questi metodi di fabbrica hanno tipi identici.
  • Il tipo di ritorno di questi metodi factory appartiene alla stessa gerarchia di ereditarietà.

Se esiste la comunanza, puoi creare un'interfaccia con un metodo che ha la firma e il tipo di ritorno. Quindi, puoi rendere questi metodi di fabbrica richiamabili da un client che conosce solo questa interfaccia.

scusa ma devo smettere di scrivere ora ...

    
risposta data 16.12.2014 - 05:02
fonte
0

Avendo un metodo in Factory Method, puoi personalizzare facilmente il comportamento di una singola classe semplicemente derivando una nuova classe da esso e sovrascrivendo un singolo metodo. Questo è più semplice del dover creare una classe factory completamente nuova per eseguire la stessa personalizzazione.

Tuttavia, se è necessario personalizzare più classi allo stesso modo, utilizzare un oggetto Factory separato è più semplice, perché in tal caso è sufficiente creare una singola nuova classe e iniettare oggetti di tale classe in tutti i diversi client.

In realtà, Factory è uno schema molto più utile del metodo Factory perché nella maggior parte delle situazioni esiste più di un client e quindi Factory può essere facilmente condiviso senza creare un gran numero di sottoclassi in una varietà di luoghi diversi nell'ereditarietà gerarchia. Favorisce anche la composizione sull'ereditarietà, che è una strategia di progettazione comunemente raccomandata in questi giorni. Il Metodo di Fabbrica sta quindi cadendo in disgrazia ed è relativamente usato raramente rispetto a Fabbrica.

    
risposta data 15.11.2014 - 13:09
fonte
0

Questo Client rispetto a Consumer è la funzione di definizione core ogni volta che il modello di creazione è Factory Method o Abstract Factory . Se Client e Consumer sono della stessa classe, allora è Factory method , se sono diversi, è un Abstract factory .

If so, why can't the Creator method in the Factory Method be put in a separate class?

Hai appena creato Abstract Factory pattern.

Similarly, why can't the Creator class in the Abstract Factory be the same class as the Client?

Quindi hai ridotto l'intero Abstract Factory in Factory Method .

    
risposta data 15.11.2014 - 22:19
fonte

Leggi altre domande sui tag