Perché il modello di progettazione del metodo di fabbrica è più utile che avere lezioni e chiamarle individualmente?


32

Dai modelli di design "Gang of Four", c'è il metodo Factory:

class Factory(product)
  case product
  when a
    new A
  when b
    new B
  when c
    new C
end

new Factory(a)

Perché questo è più utile che avere tre classi, a, b, e ce chiamandoli singolarmente?


1
Cosa intendi esattamente? Perché non istanziare tutti e tre? È questo che vuoi dire?
Neil,

1
@Neil No, nel modello di fabbrica esistono tutte le classi come fratelli. Perché chiamare la fabbrica per accedere indirettamente alle classi a, b, c?
alt

3
questo in realtà non sembra il modello del metodo factory per me, semmai è più vicino alla fabbrica astratta
jk.

2
Perché in fase di progettazione non sai quale delle 3 classi devi istanziare.
MrWhite,

Risposte:


54

Perché il tuo esempio non è abbastanza complicato. Per uno scenario così semplice non ha nemmeno senso utilizzare un modello avanzato.

Ma se devi conoscere più del prodotto per costruire A, B o C e non puoi avere accesso diretto a quella conoscenza, allora è utile. Quindi stai usando la fabbrica come centro di conoscenza per la produzione degli oggetti necessari.

Forse quegli oggetti hanno bisogno di un riferimento a qualche oggetto X, che la factory può fornire, ma il tuo codice nel punto in cui vuoi costruire A, B o C non può o non dovrebbe avere accesso a X. Forse quando hai X crei A e B ma se hai il tipo Y allora crei C.

Considera anche che alcuni oggetti potrebbero aver bisogno di 20 dipendenze per creare; cosa poi? Andare a caccia di quelle dipendenze in un luogo in cui non dovrebbero essere accessibili potrebbe essere problematico.


13
+1 per chiarire che il modello Factory non è sempre l'approccio migliore.
Neil,

1
Perché il tuo esempio non è abbastanza complicato. Per uno scenario così semplice non ha nemmeno senso utilizzare un modello avanzato. Quindi cosa faresti in questo caso? Inline la costruzione condizionale?
pdr,

Può essere solo un metodo che prende il prodotto e restituisce ciò di cui hai bisogno per renderlo riutilizzabile, quindi non deve essere in linea. Se tale metodo cresce in qualcosa di più grande, o viene utilizzato in diverse altre classi, è possibile rifattarlo in classi diverse.
Mateusz,

Il motivo si chiama Metodo di fabbrica per un motivo. Il metodo non deve appartenere a una classe diversa per essere un metodo Factory (anche se spesso lo è).
pdr,

Mi è mancato il "Metodo", quindi hai ragione, signore.
Mateusz,

23

Un modello di fabbrica è generalmente più complesso di così. Una fabbrica decide su determinati criteri quale istanza creare / restituire. Invece, quando non si utilizza la fabbrica, il codice verrà utilizzato più volte in diverse posizioni nel codice.

Ad esempio, considerare quanto segue: è necessario caricare i dati da un DB, ma si dispone di un DB centrale per l'integrazione con molti dati e uno più piccolo in memoria su ciascun dev-PC. Nel tuo codice chiedi a una factory di ottenere un handle di DB e la factory restituisce una di quelle che dipendono, ad esempio, da un file di configurazione.


20

Il modello Metodo di fabbrica estrae il processo decisionale dalla classe chiamante. Questo ha diversi vantaggi:

Riutilizzo. Se voglio creare un'istanza in molti luoghi, non devo ripetere la mia condizione, quindi quando arrivo ad aggiungere una nuova classe, non corro il rischio di perderne una.

Unità-Testabilità. Posso scrivere 3 test per la factory, per assicurarmi che restituisca i tipi corretti nelle condizioni corrette, quindi la mia classe chiamante deve solo essere testata per vedere se chiama la factory e quindi i metodi richiesti sulla classe restituita. Non ha bisogno di sapere nulla sull'implementazione della fabbrica stessa o delle classi concrete.

Estensibilità. Quando qualcuno decide che dobbiamo aggiungere una nuova classe D a questa fabbrica, nessuno del codice chiamante, né test unitari o implementazione, deve mai essere detto. Creiamo semplicemente una nuova classe D ed estendiamo il nostro metodo di fabbrica. Questa è la definizione stessa di principio aperto-chiuso .

È anche possibile creare una nuova classe di fabbrica e renderli sostituibili a caldo, se la situazione lo richiede, ad esempio se si desidera poter attivare e disattivare la classe D durante il test. Mi sono imbattuto in questa situazione solo una volta, ma è stato estremamente utile.

Come è stato detto, il modello di fabbrica non è sempre la strada da percorrere. Ma, ovunque vedi un'istanza condizionale, dovresti pensarci un attimo.


14

I principali vantaggi del modello Factory sono duplici:

  1. I luoghi che richiedono un'implementazione del prodotto non devono sapere come costruirne uno. La fabbrica detiene tali informazioni.

    Vuoi sapere quali argomenti passare al particolare costruttore? O quali dipendenze devi iniettare? O come registrare la classe di implementazione con il database dopo che è stata completamente configurata? No? Lascia che la fabbrica si occupi di tutta quella roba.

  2. I luoghi che richiedono un'implementazione del prodotto non devono sapere al momento della descrizione del modulo (ovvero al momento della compilazione) quale sia il nome della classe di implementazione.

    Pertanto, anon è necessario avere nulla a che fare con A; il "cosa costruire" può essere descritto in termini di proprietà non funzionali desiderate, e non solo il nome. Questo è molto più flessibile.

Il rovescio della medaglia è che dove sai cosa fare e come farlo, ottieni più complessità quando usi una fabbrica. La soluzione è semplice: non usare una fabbrica quando non ha senso!


2

Vorrei pensare ai modelli di design in termini di classi come "persone", e i modelli sono modi in cui le persone si parlano.

Quindi, per me il modello di fabbrica è come un'agenzia di collocamento. Hai qualcuno che avrà bisogno di un numero variabile di lavoratori. Questa persona potrebbe conoscere alcune informazioni di cui ha bisogno nelle persone che assumono, ma il gioco è fatto.

Quindi, quando hanno bisogno di un nuovo dipendente, chiamano l'agenzia di collocamento e dicono loro di cosa hanno bisogno. Ora, per assumere effettivamente qualcuno, devi conoscere un sacco di cose - benefici, verifica dell'ammissibilità, ecc. Ma la persona che assume non ha bisogno di sapere nulla di tutto ciò - l'agenzia di assunzione gestisce tutto ciò.

Allo stesso modo, l'utilizzo di una Factory consente al consumatore di creare nuovi oggetti senza dover conoscere i dettagli di come vengono creati o quali sono le loro dipendenze: devono solo fornire le informazioni che desiderano effettivamente.

Cortesia


1

Il modello Factory è il modello di progettazione più abusato e abusato.

Mi sono imbattuto in numerosi casi in cui una classe Factory è codificata quando un semplice costruttore sarebbe adeguato.

Non utilizzare una classe di fabbrica a meno che: -

  • Dipendi da una risorsa esterna ma non sai esattamente quale ancora.
  • La costruzione è costosa e vuoi costruirla una volta e riutilizzarla più volte.
  • La costruzione di una nuova istanza dipende da quali istanze sono già state costruite (ad es. Il tuo può avere solo cinque connessioni o, dovresti usare un numero ID di connessione uno in più rispetto all'ultimo numero utilizzato).

0

Utilizzare il metodo Factory quando si crea un'istanza di una sottoclasse e il codice client non deve essere responsabile per decidere quale particolare sottoclasse è istanziata.

È utile perché ti impedisce di cambiare il codice client quando devi cambiare quale classe viene istanziata. La modifica del codice esistente è una cattiva pratica perché in genere è soggetta a errori.

Un esempio potrebbe essere la presenza di sottoclassi, in cui ciascuna ordina i dati in ordine crescente, ma in modo diverso. Ogni modo è ottimale per un particolare tipo di dati. es: dati parzialmente ordinati, dati che sono numeri ecc. Il codice client è una classe che gestisce solo la stampa dei dati. Avere il codice che decide quale classe di ordinamento viene istanziata nella classe client la renderebbe una classe complessa. In altre parole, avendo più di una responsabilità, in questo caso, decidere quale classe di ordinamento è ottimale e stampare i dati. Inserendo il codice che decide quale classe di ordinamento viene istanziata in una classe Factory separa le preoccupazioni in modo da non dover cambiare la classe client ogni volta che è necessario cambiare la sottoclasse di ordinamento che viene istanziata.

È un modo per coprirti il ​​culo, se puoi prevedere i cambiamenti che fai da solo in linea con il modo in cui o quale classe viene istanziata, allora le classi di fabbrica hanno senso usare. Aiuta a mantenere le lezioni concentrate sulla loro unica responsabilità e, di conseguenza, garantisce che è meno probabile che tu debba modificare il codice esistente che non è correlato.

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.