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

GoF Patterns: Abstract Factory

4 gennaio 2011

Translate in English with Google Translate
In questo articolo tratterò il pattern Abstract Factory anche conosciuto come Kit o ToolKit.

Motivazione

Si tratta di un pattern creazionale basato su oggetti e viene utilizzato per creare delle famiglie di oggetti interconnessi senza avere la necessità di conoscere dettagli implementativi.
L’intento del pattern è quello di creare delle interfacce che, attraverso l’implementazione di classi concrete, consentano di lavorare con una varietà di elementi che presentano le stesse funzionalità ma con diverse implementazioni.

Partecipanti e Struttura

Questo pattern è composto dai seguenti partecipanti:

  1. AbstractFactory: interfaccia di esposizione di operazioni realizzate dai prodotti concreti
  2. ConcreteFactory: implementazione delle operazioni per la creazione degli oggetti dei prodotti
  3. AbstractProduct: interfaccia di esposizione delle operazioni dei prodotti concreti
  4. ConcreteProduct: implementazione delle operazioni dei prodotti concreti
  5. Client: invocazione delle interfacce per la creazione dei prodotti
Abstract Factory

Abstract Factory

Conseguenze

Tale pattern presenta i seguenti vantaggi/svantaggi:

  1. isolamento delle classi concrete: il client non ha modo di instanziare direttamente le classi concrete, ma può creare le instanze alle classi semplicemente tramite le interfacce.
  2. semplificazione della modifica delle relazioni: le relazioni tra le classi concrete possono essere facilmente modificate senza pregiudicare il client che, poichè non ha visibilità della struttura implementativa, non avrà nessuna ricaduta sulle modifiche effettuate.
  3. promozione della consistenza tra i prodotti: AbstractProduct spinge la coesione tra prodotti diversi
  4. difficoltà nell’aggiungere nuovi prodotti: la creazione di nuovi prodotti comporta delle modifiche in AbstractFactory e tutte le classi figlie e questa modifica non è indolore.

Implementazione

L’esempio che viene trattato nel GOF è quello relativo alla creazione di una maschera che preveda una combo di scelta ed un pulsante di invio. La renderizzazione sarà distinta a seconda del look-and-feel scelto che potrà essere Motif o Window

Vediamo come si presenta il pattern in UML in base alle richieste:

Abstract Factory Pattern

Abstract Factory Pattern

In questo caso abbiamo:

  • 1 interfaccia ( AbstractFactory ) dal nome LookAndFeel che verrà implementata dalle classi concrete ( ConcreteFactory )  MotifLookAndFeel e WindowLookAndFeel
  • 2 interfacce di prodotto ( AbstractProduct ) dal nome Combo e Button rispettivamente per la combo e per il bottone implemetate dalla rispettive classi concrete di prodotto ( ConcreteProduct )  MotifButton/WindowButton e MotifCombo/WindowCombo

Vediamo l’implementazione in Java del pattern.

1. Cominciamo con il vedere l’interfaccia e le implementazioni della Factory

package patterns.abstractFactory;
public interface LookAndFeel {
    Button createButton();
    Combo createCombo();
}
package patterns.abstractFactory;
public class MotifLookAndFeel implements LookAndFeel {

    @Override
    public Button createButton() {
        return new MotifButton();
    }

    @Override
    public Combo createCombo() {
        return new MotifCombo();
    }

}
package patterns.abstractFactory;
public class WindowLookAndFeel implements LookAndFeel {

    @Override
    public Button createButton() {
        return new WindowButton();
    }

    @Override
    public Combo createCombo() {
        return new WindowCombo();
    }

}

2. Vediamo l’interfaccia e le implementazioni del Product, in particolare del Button

package patterns.abstractFactory;
public interface Button {
    Button create();
}
package patterns.abstractFactory;
public class MotifButton implements Button {

    @Override
    public Button create() {
        System.out.println("Creazione MotifButton completata");
        return this;
    }

}
package patterns.abstractFactory;
public class WindowButton implements Button {

    @Override
    public Button create() {
        System.out.println("Creazione WindowButton completata");
        return this;
    }

}

3. Vediamo l’interfaccia e le implementazioni del Product, in particolare del Combo:

package patterns.abstractFactory;
public interface Combo {
    Combo create();
}
package patterns.abstractFactory;
public class MotifCombo implements Combo {

    @Override
    public Combo create() {
        System.out.println("Creazione MotifCombo completata");
        return this;
    }

}
package patterns.abstractFactory;
public class WindowCombo implements Combo {

    @Override
    public Combo create() {
        System.out.println("Creazione WindowCombo completata");
        return this;
    }

}

4. Vediamo l’invocazione del Client

package patterns.abstractFactory;
public class Client {

    public static void main(String[] args) {
        LookAndFeel lookAndFeel = null;
        if (args[0].equals("window"))
            lookAndFeel = new WindowLookAndFeel();
        else
            lookAndFeel = new MotifLookAndFeel();

        Button button = lookAndFeel.createButton();
        button.create();
        Combo combo = lookAndFeel.createCombo();
        combo.create();

    }

}

Eseguiamo la classe Client e passiamo come parametro la stringa window:

$JAVA_HOME/bin/java patterns.abstractFactory.Client window
Creazione WindowButton completata
Creazione WindowCombo completata

Eseguiamo la classe Client e passiamo come parametro la stringa motif:

$JAVA_HOME/bin/java patterns.abstractFactory.Client motif
Creazione MotifButton completata
Creazione MotifCombo completata

Vediamo come in base al parametro passato vengano creati degli oggetti Product diversi che si basano sul look-and-feel scelto.

Categorie:GOF Pattern, java
  1. Francesco
    29 luglio 2013 alle 7:24 PM

    Pure se passi come parametro la stringa ‘abracadabra’ (basta che sia diversa da ‘window’), ti crea sempre il MotifLookAndFeel😉 Ahh … quell’ else così solitario! ^__^

    • 29 luglio 2013 alle 7:44 PM

      Si tratta di un ELSE a doppio senso, del tipo: qualunque cosa diversa da “window”… va bene!🙂

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