Technopedia Center
PMB University Brochure
Faculty of Engineering and Computer Science
S1 Informatics S1 Information Systems S1 Information Technology S1 Computer Engineering S1 Electrical Engineering S1 Civil Engineering

faculty of Economics and Business
S1 Management S1 Accountancy

Faculty of Letters and Educational Sciences
S1 English literature S1 English language education S1 Mathematics education S1 Sports Education
teknopedia

teknopedia

teknopedia

teknopedia

teknopedia

teknopedia
teknopedia
teknopedia
teknopedia
teknopedia
teknopedia
  • Registerasi
  • Brosur UTI
  • Kip Scholarship Information
  • Performance
  1. Weltenzyklopädie
  2. Factory method - Teknopedia
Factory method - Teknopedia
Schema logico del Factory method in UML
Schema logico del Factory method in LePUS3

Nella programmazione ad oggetti, il factory method è uno dei design pattern fondamentali per l'implementazione del concetto di factory. Come altri pattern creazionali, esso indirizza il problema della creazione di oggetti senza specificarne l'esatta classe. Questo pattern raggiunge il suo scopo fornendo un'interfaccia per creare un oggetto, ma lascia che le sottoclassi decidano quale oggetto istanziare.[1]

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. Il factory method indirizza questi problemi definendo un 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à

[modifica | modifica wikitesto]

Il pattern factory può essere utilizzato quando:

  • La creazione di un oggetto preclude il suo riuso senza una significativa duplicazione di codice.
  • La creazione di un oggetto richiede l'accesso ad informazioni o risorse che non dovrebbero essere contenute nella classe di composizione.
  • La gestione del ciclo di vita degli oggetti gestiti deve essere centralizzata in modo da assicurare un comportamento coerente all'interno dell'applicazione.

I metodi di factory sono spesso utilizzati in toolkit e framework, dove il codice delle librerie necessita di poter creare oggetti il cui tipo è implementato nelle sottoclassi delle applicazioni che utilizzano il framework. Essi sono, inoltre, utilizzati nel Test Driven Development per porre le classi sotto test.[2] Se una classe pippo crea un oggetto Paperino 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 Paperino è posta nella funzione virtuale del factory createPaperino nella classe pippo. Per il test, TestPippo (una sottoclasse di pippo) può essere creata, con il metodo createPaperino ridefinito per creare e restituire un oggetto di FakePaperino, un oggetto di mock-up. Gli unit test possono, quindi, usare TestPippo per testare le funzionalità di pippo senza incorrere negli effetti collaterali dati dall'uso dell'oggetto reale Paperino.

Esempi di implementazione

[modifica | modifica wikitesto]

Java

[modifica | modifica wikitesto]

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 è simile a quello presente sul libro Design Patterns). Il gioco regolare può usare un modello del tipo:

public class MazeGame {
  public MazeGame() {
     Room room1 = makeRoom();
     Room room2 = makeRoom();
     room1.connect(room2);
     this.addRoom(room1);
     this.addRoom(room2);
  }

  protected Room makeRoom() {
     return new OrdinaryRoom();
  }
}

Nel codice summenzionato, il costruttore MazeGame è un template che fornisce della logica comune e fa riferimento al metodo factory makeRoom 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 makeRoom per l'implementazione delle stanze magiche:

public class MagicMazeGame extends MazeGame {
  @Override
  protected Room makeRoom() {
      return new MagicRoom();
  }
}

PHP

[modifica | modifica wikitesto]

Un esempio in PHP è qui riportato:

// uso di Factory Method design pattern

interface FabbricaAutomobile 
{
    public function costruiscoAuto(auto $auto);
}

interface Auto 
{
    public function costruiscoTelaio();
    public function costruiscoMotore();
    public function costruiscoInterni();
    public function assembloAuto();
    public function testoAuto();
}

// uso di Prototype design pattern

abstract class PrototipoAuto
{
    protected $telaio;
    protected $motore;
    protected $interni;
    protected $assemblato;
    protected $test;
    abstract function __clone();
    abstract function modificaNome($nome);
}

class FabbricaModello implements FabbricaAutomobile 
{
    public function costruiscoAuto(auto $auto) 
    {
        return $auto;
    }
}

class Fiat extends PrototipoAuto implements Auto 
{
    private $nome;
    
    public function __construct()
    {
        $this->telaio = 0;
        $this->motore = 0;
        $this->interni = 0;
        $this->assemblato = 0;
        $this->test = 0;
        $this->nome = "Fiat";
        echo "Costruzione {$this->nome} iniziata\n";
    }
    
    function __clone()
    {
        echo "Costruzione clone {$this->nome} iniziata\n";
    }
    
    public function modificaNome($nome)
    {
        echo "Nome {$this->nome} modificato ";
        $this->nome = $nome;
        echo "in {$this->nome}\n";
        return $this;
    }
    
    public function costruiscoTelaio()
    {
        echo "Telaio {$this->nome} costruito\n";
        $this->telaio = 1;
        return $this;
    }
    
    public function costruiscoMotore()
    {
        echo "Motore {$this->nome} costruito\n";
        $this->motore = 1;
        return $this;
    }
    
    public function costruiscoInterni()
    {
        echo "Interni {$this->nome} costruiti\n"; 
        $this->interni = 1;
        return $this;
    }
    
    public function assembloAuto()
    {
        echo "{$this->nome} assemblata\n";
        $this->assemblato = 1;
        return $this;
    }
    
    public function testoAuto()
    {
        if($this->telaio && $this->motore && $this->interni && $this->assemblato)
        {
            echo "Test {$this->nome} superato\n";
            $this->test = 1;
        }
        else
        {
            echo "Test {$this->nome} non superato\n";
            $this->test = 0;
        }
        
        return $this;
    }
}

class Lancia extends PrototipoAuto implements Auto 
{
    private $nome;
    
    public function __construct()
    {
        $this->telaio = 0;
        $this->motore = 0;
        $this->interni = 0;
        $this->assemblato = 0;
        $this->test = 0;
        $this->nome = "Lancia";
        echo "Costruzione {$this->nome} iniziata\n";
    }
    
    function __clone()
    {
        
    }
    
    public function modificaNome($nome)
    {
        return $this;
    }
    
    public function costruiscoTelaio()
    {
        echo "Telaio {$this->nome} costruito\n";
        $this->telaio = 1;
        return $this;
    }
    
    public function costruiscoMotore()
    {
        echo "Motore {$this->nome} acquistato\n";
        $this->motore = 1;
        return $this;
    }
    
    public function costruiscoInterni()
    {
        echo "Interni {$this->nome} costruiti\n"; 
        $this->interni = 1;
        return $this;
    }
    
    public function assembloAuto()
    {
        echo "{$this->nome} assemblata\n";
        $this->assemblato = 1;
        return $this;
    }
    
    public function testoAuto()
    {
        if($this->telaio && $this->motore && $this->interni && $this->assemblato)
        {
            echo "Test {$this->nome} superato\n";
            $this->test = 1;
        }
        else
        {
            echo "Test {$this->nome} non superato\n";
            $this->test = 0;
        }
        
        return $this;
    }
}

class NuovaAuto
{
    private $fabbricaModello;

    public function __construct()
    {
        $this->fabbricaModello = new FabbricaModello();
        echo "\n--Nuova Fiat usando Factory Method--\n";
        $fiat = new Fiat();
        $this->fabbricaModello->costruiscoAuto($fiat)->costruiscoTelaio()->costruiscoMotore()->costruiscoInterni()->assembloAuto()->testoAuto();
        echo "\n--Nuova Lancia usando Factory Method--\n";
        $this->fabbricaModello->costruiscoAuto(new Lancia())->costruiscoTelaio()->costruiscoMotore()->costruiscoInterni()->testoAuto()->assembloAuto()->testoAuto();
        echo "\n--Nuova Bianchi usando Factory Method e Prototype--\n";
        // usando prototype si crea un clone dell'oggetto Fiat, infatti si può eseguire "testAuto" subito dopo "modificaNome"
        $this->fabbricaModello->costruiscoAuto(clone $fiat)->modificaNome("Bianchi")->testoAuto();
    }
}

$nuoveAuto = new NuovaAuto();

//Risultato: #quanton81

//--Nuova Fiat usando Factory Method--
//Costruzione Fiat iniziata
//Telaio Fiat costruito
//Motore Fiat costruito
//Interni Fiat costruiti
//Fiat assemblata
//Test Fiat superato
//
//--Nuova Lancia usando Factory Method--
//Costruzione Lancia iniziata
//Telaio Lancia costruito
//Motore Lancia acquistato
//Interni Lancia costruiti
//Test Lancia non superato
//Lancia assemblata
//Test Lancia superato
//
//--Nuova Bianchi usando Factory Method e Prototype--
//Costruzione clone Fiat iniziata
//Nome Fiat modificato in Bianchi
//Test Bianchi superato

Limitazioni

[modifica | modifica wikitesto]

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 perché 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

[modifica | modifica wikitesto]
  1. ^ Gang Of Four
  2. ^ Feathers, Michael, Working Effectively with Legacy Code, Upper Saddle River, NJ, Prentice Hall Professional Technical Reference, ottobre 2004, ISBN 978-0-13-117705-5.

Voci correlate

[modifica | modifica wikitesto]
  • Design pattern

Altri progetti

[modifica | modifica wikitesto]

Altri progetti

  • Wikimedia Commons
  • Collabora a Wikimedia Commons Wikimedia Commons contiene immagini o altri file su factory method
V · D · M
Design pattern
CreazionaliAbstract factory · Builder · Factory · Prototype · Singleton
StrutturaliAdapter · Bridge · Composite · Container pattern · Decorator · Façade · Flyweight · Proxy
ComportamentaliChain-of-responsibility · Command · Interpreter · Iterator · Mediator · Memento · Observer · State · Strategy · Template method · Visitor
Pattern di concorrenzaActive object · Balking · Binding properties · Double-checked locking · Event-based asynchronous · Guarded suspension · Join · Lock · Monitor · Proactor · Reactor · Read write lock · Scheduler · Thread pool · Thread-local storage
Pattern architetturaliFront controller · Interceptor · MVC · n-tier · Specification · Publish–subscribe · Naked objects · Service locator · Active record · Identity map · Data Access Object · Data transfer object · ADR · Inversione del controllo
Altri
pattern
Blackboard · Business delegate · Composite entity · Dependency injection · Intercepting filter · Lazy loading · Mock object · Null object · Object pool · Servant · Twin · Type tunnel
LibriDesign Patterns · Enterprise Integration Patterns
PersoneChristopher Alexander · Erich Gamma · Ralph Johnson · John Vlissides · Grady Booch · Kent Beck · Ward Cunningham · Martin Fowler · Robert Martin · Jim Coplien · Douglas Schmidt · Linda Rising
ComunitàThe Hillside Group · The Portland Pattern Repository
  Portale Informatica: accedi alle voci di Teknopedia che trattano di informatica
Estratto da "https://it.wikipedia.org/w/index.php?title=Factory_method&oldid=145215380"

  • Indonesia
  • English
  • Français
  • 日本語
  • Deutsch
  • Italiano
  • Español
  • Русский
  • فارسی
  • Polski
  • 中文
  • Nederlands
  • Português
  • العربية
Pusat Layanan

UNIVERSITAS TEKNOKRAT INDONESIA | ASEAN's Best Private University
Jl. ZA. Pagar Alam No.9 -11, Labuhan Ratu, Kec. Kedaton, Kota Bandar Lampung, Lampung 35132
Phone: (0721) 702022