Friday, October 12, 2012

Patron : Fabrique abstraite (Abstract Factory)

Le patron fabrique abstraite est de type création.

Il se base sur la patron fabrique mais ajoute une couche d'abstraction de plus. Ce patron permet de regrouper des fabriques qui ont un theme commun sans spécifier les classes concretes.



Dans le code ci-dessous, voit qu'il y a 2 fabriques qui font plus ou moins la meme chose. Alors on les regroupe et on crée la classe AbstractFactoryGuerrier.
On peut constater que dans la classe Jeu, on ne spécifie jamais "new Katana()" car la responsabilité de créer un katana se trouve dans la fabrique.



Jeu.java
public class Jeu {

 public static void main(String[] args) {
  Jeu jeu = new Jeu();
  jeu.jouer();
 }
 
 public void jouer() {
  AbstractFactoryGuerrier factory = createFactory("Lancelot");
  preparerArme(factory);
  preparerArmure(factory);
  
  factory = createFactory("Musashi");
  preparerArme(factory);
  preparerArmure(factory);
 }
 
 // on cree la factory correspondante au "type" recu en parametre
 public AbstractFactoryGuerrier createFactory(String type) {
  System.out.println("\n   Factory pour " + type);
  
  if("Lancelot".equals(type))
   return new FactoryChevalier();
  else
   return new FactorySamourai();
 }
 
 // on prepare une arme (que ce soit une epee ou un katana)
 public void preparerArme(AbstractFactoryGuerrier factory) {
  Arme arme = factory.creerArme();
  arme.attaquer();
 }
 
 // on prepare une armure (que ce soit une cuirasse ou une yoroi)
 public void preparerArmure(AbstractFactoryGuerrier factory) {
  Armure armure = factory.creerArmure();
  armure.proteger();
 }
}
AbstractFactoryGuerrier.java
abstract class AbstractFactoryGuerrier {
 abstract Armure creerArmure();
 abstract Arme creerArme();
}
FactoryChevalier.java
public class FactoryChevalier extends AbstractFactoryGuerrier{
 Armure creerArmure() {
  return new Cuirasse();
 }

 Arme creerArme() {
  return new Epee();
 }
}
FactorySamourai.java
public class FactorySamourai extends AbstractFactoryGuerrier{
 Armure creerArmure() {
  return new Yoroi();
 }

 Arme creerArme() {
  return new Katana();
 }
}
Arme.java
abstract class Arme {
 abstract void attaquer();
}
Epee.java
public class Epee extends Arme{
 void attaquer() {
  System.out.println("Epee pour transperser les armures");
 }
}
Katana.java
public class Katana extends Arme{
 void attaquer() {
  System.out.println("Katana tranche un cheveu en deux");
 }
}
Armure.java
abstract class Armure {
 abstract void proteger();
}
Cuirasse.java
public class Cuirasse extends Armure{
 void proteger() {
  System.out.println("Cuirasse lourde mais protectrice");
 }
}
Yoroi.java
public class Yoroi extends Armure{
 void proteger() {
  System.out.println("Yoroi souple qui permet de se déplacer facilement");
 }
}


Et le résultat de l'éxecution:
Factory pour Lancelot
Epee pour transperser les armures
Cuirasse lourde mais protectrice 

Factory pour Musashi
Katana tranche un cheveu en deux
Yoroi souple qui permet de se déplacer facilement

No comments: