Factory method: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
DaimonBot (discussione | contributi)
m Orfanizzo Java (linguaggio)
Botcrux (discussione | contributi)
m Bot: fix wl, replaced: Design Patterns patterns → Design pattern
 
(18 versioni intermedie di 14 utenti non mostrate)
Riga 2:
[[File:Factory Method pattern in LePUS3.png|thumb|upright=1.4|Schema logico del Factory method in [[LePUS3]]]]
 
Nella [[Programmazione orientata agli oggetti|programmazione ad oggetti]], il '''Factoryfactory Methodmethod''' è uno dei [[design pattern]] fondamentali per l'implementazione del concetto di [[factory (informatica)|factoriesfactory]]. Come altri [[pattern creazionali]], esso indirizza il problema della creazione di [[oggetto (informatica)|oggetti]] senza specificarne l'esatta [[classe (informatica)|classe]]. Questo pattern raggiunge il suo scopo fornendo un'[[interfaccia (informatica)|interfaccia]] per creare un oggetto, ma lascia che le sottoclassi decidano quale oggetto istanziare.<ref>[[Design Patterns|Gang Of Four]]</ref>
 
La creazione di un oggetto può, spesso, richiedere processi complessi la cui collocazione all'interno della classe di composizione potrebbe non essere appropriata. Esso può, inoltre, comportare la duplicazione di codice, richiedere informazioni non accessibili alla classe di composizione, o non provvedere un sufficiente livello di [[astrazione (informatica)|astrazione]]. Il '''factory method''' indirizza questi problemi definendo un [[metodo (informatica)|metodo]] separato per la creazione degli oggetti; tale metodo può essere ridefinito dalle sottoclassi per definire il tipo derivato di prodotto che verrà effettivamente creato.
 
== Applicabilità ==
Riga 19:
|editore=Prentice Hall Professional Technical Reference
|città=Upper Saddle River, NJ
}}</ref> Se una classe <code>Pippopippo</code> crea un oggetto <code>Paperino</code> che non può essere posto sotto una suite automatica di [[unit testing]] (ad esempio perché non può accedere ad una risorsa di produzione cui ha bisogno, come una base dati), allora la creazione dell'oggetto <code>Paperino</code> è posta nella [[funzione virtuale]] del factory <code>createPaperino</code> nella classclasse <code>Pippopippo</code>. Per il test, <code>TestPippo</code> (una sottoclasse di <code>Pippopippo</code>) può essere creata, con il metodo <code>createPaperino</code> ridefinito per creare e ritornarerestituire un oggetto di <code>FakePaperino</code>, un oggetto di mock-up. Gli unit test possono, quindi, usare <code>TestPippo</code> per testare le funzionalità di <code>Pippopippo</code> senza incorrere negli effetti collaterali dati dall'uso dell'oggetto reale <code>Paperino</code>.
 
== Esempi di implementazione ==
Riga 25:
Un gioco del labirinto può essere giocato in due modi, uno con stanze regolari che sono connesse solo a quelle adiacenti e uno con stanze magiche che possono trasportare i giocatori in stanze casuali lungo tutto il labirinto (questo esempio in [[Java (linguaggio di programmazione)|Java]] è simile a quello presente sul libro ''[[Design Patterns]]''). Il gioco regolare può usare un modello del tipo:
 
<sourcesyntaxhighlight lang=Java>
public class MazeGame {
public MazeGame() {
Riga 39:
}
}
</syntaxhighlight>
</source>
 
Nel codice summenzionato, il costruttore <code>MazeGame</code> è un template che fornisce della logica comune e fa riferimento al metodo factory <code>makeRoom</code> che incapsula la logica di creazione delle stanza in modo che le stanze possano essere utilizzate nelle sottoclassi. Per implementare l'altra modalità di gioco, infatti, è necessario solo ridefinire <code>makeRoom</code> per l'implementazione delle stanze magiche:
 
<sourcesyntaxhighlight lang=Java>
public class MagicMazeGame extends MazeGame {
@Override
Riga 50:
}
}
</syntaxhighlight>
</source>
 
=== PHP ===
Un esempio in [[PHP]] è qui riportato:
<sourcesyntaxhighlight lang=PHP"php">
// uso di Factory Method design pattern
 
interface FabbricaAutomobile
{
public function costuiscoAutocostruiscoAuto(auto $auto);
}
 
Riga 66:
public function costruiscoTelaio();
public function costruiscoMotore();
public function costuiscoInternicostruiscoInterni();
public function assembloAuto();
public function testoAuto();
Riga 86:
class FabbricaModello implements FabbricaAutomobile
{
public function costuiscoAutocostruiscoAuto(auto $auto)
{
return $auto;
Riga 134:
}
public function costuiscoInternicostruiscoInterni()
{
echo "Interni {$this->nome} costruiti\n";
Riga 204:
}
public function costuiscoInternicostruiscoInterni()
{
echo "Interni {$this->nome} costruiti\n";
Riga 244:
echo "\n--Nuova Fiat usando Factory Method--\n";
$fiat = new Fiat();
$this->fabbricaModello->costuiscoAutocostruiscoAuto($fiat)->costruiscoTelaio()->costruiscoMotore()->costuiscoInternicostruiscoInterni()->assembloAuto()->testoAuto();
echo "\n--Nuova Lancia usando Factory Method--\n";
$this->fabbricaModello->costuiscoAutocostruiscoAuto(new Lancia())->costruiscoTelaio()->costruiscoMotore()->costuiscoInternicostruiscoInterni()->testoAuto()->assembloAuto()->testoAuto();
echo "\n--Nuova Bianchi usando Factory Method e Prototype--\n";
// usando prototype si crea un clone dell'oggetto Fiat, infiattiinfatti si può eseguire "testAuto" subito dopo "modificaNome"
$this->fabbricaModello->costuiscoAutocostruiscoAuto(clone $fiat)->modificaNome("Bianchi")->testoAuto();
}
}
Riga 278:
//Nome Fiat modificato in Bianchi
//Test Bianchi superato
</syntaxhighlight>
</source>
 
== Limitazioni ==
Ci sono tre limitazioni, all'uso di questo metodo. Il primo è relativo al [[refactoring]], gli altri due sono relativi all'estensione di classi.
 
* La prima limitazione consiste nel fatto che il ''refactoring'' di una classe esistente causa il malfunzionamento dei client esistenti.
* La seconda limitazione è dovuta al fatto che, poiché il pattern si basa sull'uso di costruttori privati, la classe non può essere estesa. Ogni sottoclasse dovrebbe invocare il costruttore ereditato, ma non può farlo nella misura in cuiperché quest'ultimo è privato.
* La terza limitazione è dovuta al fatto che, se estendiamo una classe (ad esempio rendendo il costruttore 'protected'; rischioso ma possibile), le sottoclassi devono precedere la reimplementazione di tutti i metodi di ''factory'' con la stessa dichiarazione. La possibilità, fornita da alcuni linguaggi, di usare le classi ''reflection'' può, tuttavia, risolvere questo problema.
 
== Note ==
Riga 291:
 
== Voci correlate ==
* [[Design pattern]]
* ''[[Design Patterns]]'', il libro della [[gang of four]] che ha introdotto il pattern
* [[Design pattern]], introduzione generale ai design pattern
 
== Altri progetti ==
{{interprogetto|commons=Factory method}}
 
{{Design Patterns Patternspattern}}
{{Portale|informatica}}
 
[[Categoria:PatternDesign pattern]]