Factory Method

Pattern descritto in Design Pattern.

Lo scopo del pattern Factory Method (aka Costruttore Virtuale) é quello di definire un'interfaccia per la creazione di un oggetto, ma di lasciar decidere alle sottoclassi quale classe istanziare.

Partecipanti
  • Product: definisce l'interfaccia dell'oggetto creato dalla factory
  • ConcreteProduct: implementa l'interfaccia Product
  • Creator: dichiara il factory method
  • ConcreteCreator: ridefinisce il factory method
Esempio

Nel mondo fantasy che modelliamo per la nostra applicazione ci sono dei "cattivi" che creano mostri che manderanno a combattere contro i nostri eroi.
Ogni "cattivo" può generare, in questa prima implementazione, tre tipi di mostri di potenza crescente.

Creator

Il nostro "cattivo" é quindi il Creator del pattern, e rispetterà questa interfaccia:

public interface BadGuy {
enum MonsterType {SIMPLE, AVERAGE, STRONG}
public Monster createMonster(MonsterType type);
}


ConcreteCreator

Ogni cattivo che usiamo nel nostro sistema implementa l'interfaccia BadGuy, ad esempio, vediamone uno:

public class Zardoz implements BadGuy {

public Monster createMonster(MonsterType type) {

switch(type) {
case SIMPLE:
return new TinMan();
case AVERAGE:
return new StrawMan();
case STRONG:
default:
return new ShyLion();
}
}
}


Product

I mostri creati dai nostri "cattivi" seguiranno questa interfaccia:

public interface Monster {
public String getName();
public int fight();
}


ConcreteProduct

Ecco qua l'esempio di uno dei mostri che popolano la nostra applicazione:

public class TinMan implements Monster {
private int strength = 3;

public String getName() {
return this.getClass().getSimpleName();
}

public int fight() {
return strength;
}
}


Test

Questo é un piccolo tester per questa implementazione del pattern:

BadGuy z = new Zardoz();
Monster monster = z.createMonster(BadGuy.MonsterType.SIMPLE);
System.out.println("Monster " + monster.getName() + " created.");
System.out.println("Monster is fighting: " + monster.fight());

BadGuy t = new Topolonek();
monster = t.createMonster(BadGuy.MonsterType.STRONG);
System.out.println("Monster " + monster.getName() + " created.");
System.out.println("Monster is fighting: " + monster.fight());

Notiamo che, dal punto di vista del cliente, quello che ci interessa sapere é solo il "cattivo" con cui abbiamo a che fare e il livello del mostro che vogliamo generare. Il cliente opera sull'interfaccia BadGuy, ma la decisione sul tipo effettivo di mostro creato é delegato alle classi che la implementano.

Il risultato del nostro tester sarà il seguente:

Monster TinMan created.
Monster is fighting: 3
Monster Pippok created.
Monster is fighting: 18

Nessun commento:

Posta un commento