Un metodo di fabbrica è essenzialmente solo un costruttore con un altro nome. Questo può essere utile per es. per garantire la corretta inizializzazione, registrazione o per fornire valori predefiniti senza dover sottoclasse il prodotto:
private List<WeakReference<Product>> products = ...;
public Product makeProduct(Param x) {
Product instance = new Product(x, "default value");
instance.initialize(42);
products.add(new WeakReference<>(instance));
return instance;
}
Un modello di fabbrica astratto di solito è implementato in termini di metodi di fabbrica, ma qui l'obiettivo è di lasciare il tipo di calcestruzzo non specificato fino al runtime. Quindi abbiamo un set di prodotti:
interface Product {}
class ConcreteProduct1 implements Product {}
class ConcreteProduct2 implements Product {}
E abbiamo una fabbrica astratta:
interface Factory {
public Product makeProduct();
}
Tale factory potrebbe essere utilizzata dal codice cliente: factory.makeProduct()
. Quale prodotto concreto viene utilizzato è ritardato al runtime.
class ConcreteFactory1 implements Factory {
public Product makeProduct() { return new ConcreteProduct1(); }
}
class ConcreteFactory2 implements Factory {
public Product makeProduct() { return new ConcreteProduct2(); }
}
Tipicamente, una fabbrica astratta avrà più metodi di fabbrica per una serie di tipi correlati, puoi pensare a un'istanza di fabbrica come a un "tema". Le fabbriche astratte sono anche utili per l'iniezione di dipendenza.
Il pattern metodo di fabbrica è una combinazione di metodi di fabbrica con il modello di strategia. Qui l'idea è che la nostra classe abbia bisogno di creare qualche istanza, ma permetterà alle sottoclassi di scavalcare la scelta dell'istanza. In altre parole, il cliente e la fabbrica sono uguali.
class DomainSpecificStuff {
public doDomainSpecificStuff() {
Product p = this.makeProduct();
p.frobnicate();
}
protected makeProduct() {
return new ConcreteProduct1();
}
}
class OtherDomainSpecificStuff {
@Override
protected makeProduct() {
return new ConcreteProduct2();
}
}
Quindi il modello strategico consente un'iniezione di dipendenza limitata attraverso l'uso dell'ereditarietà quando viene utilizzato come FMP.
Quindi quali sono le distinzioni utili tra il modello di metodo factory e il modello factory astratto?
-
Cliente: il client del metodo factory nel FMP è la fabbrica stessa - dopotutto è solo una rotazione del modello strategico. Il client dell'AFP è un'altra classe.
-
Numero di oggetti: in genere, l'FMP avrà un unico metodo di fabbrica, mentre l'AFP può essere utilizzato per produrre più oggetti correlati. Non è il caso che un AFP deve avere almeno due metodi di fabbrica, anche se la creazione di oggetti correlati e interdipendenti è dove l'AFP brilla.
-
Intenzione: l'AFP è una raccolta di metodi di fabbrica correlati che possono essere passati in giro nel codice cliente. L'FMP consente alle sottoclassi di sostituire una dipendenza.