Thursday, October 11, 2012

Patron : Prototype


Le patron prototype est de type création.
Il est utilisé lorsque la création d'un objet est complexe et consommatrice de temps. Pour cela, on crée juste une instance et on la clone.
Le fait de ne pas utiliser de "new Xxx()" et d'initialiser des propriétés fait gagner beaucoup de temps.

Admettons que nous sommes Saroumane et on veut construire une armée de monstres (orques et wargs) le plus rapidement possible pour combattre Sauron.
On peut faire naitre des orques ("Montre x = new Monstre()") mais cela prendrait beaucoup de temps, car on devra attendre qu'ils atteignent l'age adulte pour pouvoir se battre.
L'autre solution, et de prendre l'orque le plus fort et de le cloner! C'est beaucoup plus rapide!


Ici, la classe Monstre est une sous-classe de Cloneable et doit posséder une fonction "clone()".

Magicien.java
import java.util.ArrayList;
import java.util.Iterator;

public class Magicien {
 public static void main(String[] args) {
  Magicien saroumane = new Magicien();
  saroumane.construireArmee();
 }
 
 public Magicien() { }
 
 public void construireArmee() {
  Monstre orque = new Orque();
  orque.setName("Chef orque");
  Monstre warg = new Warg();
  orque.setName("Chef warg");
  
  Monstre monstreCloned;
  ArrayList armee = new ArrayList();
  
  // on va creer 10 soldats : 5 orques et 5 wargs
  for(int i = 0; i < 10; i++) {
   if(i%2 == 0) {
    monstreCloned = orque.clone();
    monstreCloned.setName("soldat orque " + i);
   } else {
    monstreCloned = warg.clone();
    monstreCloned.setName("soldat warg " + i);
   }
   
   armee.add(monstreCloned);
  }
  
  Iterator it =  armee.iterator();
  
  while(it.hasNext()){
   monstreCloned = it.next();
   System.out.println(monstreCloned.getName());
  }
 }
}
//ignorer les 3 balises ci-dessous
Monstre.java
public abstract class Monstre implements Cloneable{
 protected String name;
 
 public Monstre clone() {
  try {
   Monstre clone = (Monstre)super.clone();
   clone.name = this.name;
   return clone;
  } catch (CloneNotSupportedException e){
   return null;
  }
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}
Orque.java
public class Orque extends Monstre{ }

Warg.java
public class Warg extends Monstre{ }


Le résultat de l'execution est:

soldat orque 0
soldat warg 1
soldat orque 2
soldat warg 3
soldat orque 4
soldat warg 5
soldat orque 6
soldat warg 7
soldat orque 8
soldat warg 9

Et voila, maintenant Saroumane est prêt à partir en guerre!

No comments: