Home > GOF Pattern, java > GoF Patterns: Factory Method

GoF Patterns: Factory Method

10 gennaio 2011

Translate in English with Google Translate
In questo articolo tratterò il pattern Factory Method anche detto Virtual Constructor

Motivazione

Si tratta di un pattern creazionale basato su classi e viene utilizzato per creare degli oggetti senza conoscerne i dettagli ma delegando un Creator che, in base alle informazioni ricevute, saprà quale oggetto restituire. Questo pattern consente di separare il Client dal Framework  permettendo di modificare i dettagli implementativi senza dovere modificare il Client.

Partecipanti e Struttura

Questo pattern è composto dai seguenti partecipanti:

  1. Creator: dichiara la Factory che avrà il compito di ritornare l’oggetto appropriato
  2. ConcreteCreator: effettua l’overwrite del metodo della Factory al fine di ritornare l’implementazione dell’oggetto
  3. Product: definisce l’interfaccia dell’oggetto che deve essere creato dalla Factory
  4. ConcreteProduct: implementa l’oggetto in base ai metodi definiti dall’interfaccia Product

Vediamo come si presenta il Pattern Factory Method utilizzando il Class Diagram in UML:

Factory Method PatternConseguenze

Tale pattern presenta i seguenti vantaggi/svantaggi:

  1. rappresenta un gancio alle sotto-classi: tramite il Creator è possibile scegliere quale classe concreta utilizzare e decidere di cambiarla senza avere nessun impatto verso il Client
  2. consente di collegare gerarchie di classi in modo parallelo: i ConcreteCreator possono collegarsi con i ConcreteProduct e generare un collegamento parallelo tra gerarchie diverse.

Implementazione
Come esempio  pensiamo al caso in cui ci rechiamo in un centro commerciale  per acquistare un paio di scarpe sportive, in particolare da ginnastica, quindi chiediamo al commesso di turno che ci rimanda al commesso specializzato nel settore di nostro interesse che ci consegnerà le scarpe di ginnastica che cercavamo.

Vediamo come si presenta il pattern in UML in base all’esempio:

Factory Method - Esempio

Factory Method – Esempio

Vediamo come si presenta la classe Cliente:

package patterns.factoryMethod;
public class Cliente {
    public static void main(String[] args) {
        Commesso commesso = new Commesso();
        Scarpe scarpe = commesso.getScarpe("ginnastica");
        System.out.println(scarpe.getClass());
    }
}

Vediamo la definizione del prodotto nella sua definizione e nelle sue implementazioni che nel nostro caso sono vuote per semplicità:

package patterns.factoryMethod;
public interface Scarpe {
}

 

package patterns.factoryMethod;
public class ScarpeGinnastica implements Scarpe {
}

 

package patterns.factoryMethod;
public class ScarpeTennis implements Scarpe {
}

Di seguito abbiamo l’implementazioni della Factory:

package patterns.factoryMethod;
public class Commesso {
    public Scarpe getScarpe(String tipo) {
        Scarpe scarpe = null;
        if(tipo.equals("ginnastica"))
            scarpe = CommessoGinnastica.getScarpe();
        else if(tipo.equals("tennis"))
            scarpe = CommessoTennis.getScarpe();
        return scarpe;
    }
}

 

package patterns.factoryMethod;
public class CommessoGinnastica extends Commesso {
    public static Scarpe getScarpe(){
        return new ScarpeGinnastica();
    }
}

 

package patterns.factoryMethod;
public class CommessoTennis extends Commesso {
    public static Scarpe getScarpe(){
        return new ScarpeTennis();
    }
}

Eseguiamo la classe Cliente e visualizziamo l’output:

$JAVA_HOME/bin/java patterns.factoryMethod.Cliente
class patterns.factoryMethod.ScarpeGinnastica

In questo caso il cliente richiede un paio di scarpe da ginnastica e viene visualizzato di seguito l’oggetto ScarpeGinnastica

Categorie:GOF Pattern, java
  1. 3 febbraio 2012 alle 12:17 PM

    Complimenti! sto studiando ingegneria del software e ho trovato molto materiale interessante sul tuo blog!
    Continua cosi! 😉

    • 3 febbraio 2012 alle 4:13 PM

      Ti ringrazio e mi fa molto piacere che i miei articoli ti possano essere utili.

  2. Gianlu
    26 febbraio 2012 alle 6:26 PM

    Articolo utile e chiaro, non se ne trova di cosi fatti bene in giro!🙂

    • 27 febbraio 2012 alle 11:29 AM

      Ti ringrazio🙂. Spiegazioni ed esempi semplici li puoi trovare anche su Wikipedia, in particolare la sezione in inglese. Seguendo i link si accede a molti articoli e libri interessanti. In italiano trovo molto utile la guida dei pattern GoF del Prof. Franco Guidi del Politecnico di Torino.

  3. Pippo
    6 dicembre 2013 alle 8:01 PM

    scusami ma nel UML le classi ScarpeGinnastica e ScarpeTennis non dovrebbero avere la freccettina tratteggiata che indica la realizzazione essendo la classe Scarpe un interface?

    • Pippo
      6 dicembre 2013 alle 8:13 PM

      Inoltre nell UML i concreteCreator la freccia che và verso i concreteProduct perchè è un associazione e non una dipendenza?

      • 7 dicembre 2013 alle 10:18 AM

        Entrambe le tue osservazioni sono corrette. Ho notato, e mi hanno fatto notare, di aver indicato delle relazioni non corrette anche in altri Class Diagram, che dovrò correggere, spero quanto prima di fare una revisione generale. Nel frattempo ho corretto queste. Ciao e grazie.

  4. Pippo
    7 dicembre 2013 alle 11:53 AM

    Ok grazie mille sempre molto esaustivo😉
    Un ultima cosa. ma in questo caso il client ha una associazione solo con il commesso e scarpe giusto?

    • 10 dicembre 2013 alle 12:56 AM

      Si, in fondo il Client non sa della presenza di altre classi che implementano la factory ed il prodotto. Tutto ciò gli viene nascosto, disaccoppiare anche in questo caso è un approccio vincente, e ciò che fa da guida è l’ereditarietà. Ho indicato il Cliente nell’esempio del Class Diagram in modo da evidenziare le sue relazioni.

  5. 12 dicembre 2013 alle 12:49 PM

    Ciao Giuseppe. Complimenti per l’articolo. Sei stato uno dei pochi che mi ha fatto davvero capire l’utilità di questo pattern. Hai mai pensato di proporti a wikipedia? Credo che il tuo articolo sia migliore rispetto a quello che offre wikipedia.. Buona Giornata!

    • 12 dicembre 2013 alle 3:01 PM

      Grazie mille Raffaele. Con tutto il rispetto per wikipedia, devo dire che anche io a volte trovo che alcuni articoli siano poco chiari e non sempre la versione inglese migliori la qualità, ma non ho pensato di propormi e lascio ad altri l’iniziativa anche se ricevo il consenso. Buona giornata anche a te.

  1. No trackbacks yet.
I commenti sono chiusi.
%d blogger cliccano Mi Piace per questo: