Définition
Le patron Prototype est un patron de création qui définit le type d'objets à instancier en utilisant une instance prototype, et génère de nouvelles instances par duplication de ce prototype.
Catégorie
Ce patron appartient à la catégorie des patrons de création.
Structure
Ce patron se concentre sur la réplication d'objets, avec la classe Prototype comme élément central. Pour l'implémenter en Java, deux conditions sont nécessaires :
- Implémenter l'interface Cloneable. Cette interface indique à la machine virtuelle Java que la clase peut être clonée en toute sécurité. Sans cette implémentation, une exception CloneNotSupportedException est lancée lors de l'appel à clone.
- Redéfinir la méthode clone héritée de la classe Object. Étant donné que la méthode clone d'Object est protégée, la classe Prototype doit modifier sa visibilité en public pour permettre l'accès externe.
Bien que simple à comprendre, ce patron est rarement utilisé de manière isolée et s'intègre souvent avec d'autres patrons. La classe Prototype peut être abstraite selon les besoins.
Implémentation
Exemple avec une classe Document :
public class Document implements Cloneable {
private String intitule;
private double montant;
public Document(String intitule, double montant) {
this.intitule = intitule;
this.montant = montant;
}
public String getIntitule() {
return intitule;
}
public void setIntitule(String intitule) {
this.intitule = intitule;
}
public double getMontant() {
return montant;
}
public void setMontant(double montant) {
this.montant = montant;
}
@Override
public String toString() {
return "Intitulé : " + intitule + ", Montant : " + montant;
}
@Override
public Document clone() throws CloneNotSupportedException {
return (Document) super.clone();
}
}
Code de test :
public class TestDocument {
public static void main(String[] args) throws CloneNotSupportedException {
Document original = new Document("Guide Java", 29.99);
Document copie = original.clone();
copie.setIntitule("Guide Java - Copie");
System.out.println("Original : " + original);
System.out.println("Copie : " + copie);
}
}
Avantages et applications
L'utilisation du patron Prototype peut offrir de meilleures performances que l'instanciation directe via new, car la méthode clone est une méthode native qui manipule directement le flux binaire en mémoire. Cet avantage est particulièrement notable lors de la copie d'objets volumineux.
Il simplifie également le processus de création d'objets, le rendant aussi intuitif qu'un copier-coller. Ce patron est recommandé dans les scénarios nécessitant la création répétée d'objets similaires, comme dans des boucles complexes, où il peut réduire la charge de création et améliorer l'efficacité globale.
Points de vigilance
Le clonage via ce patron n'invoque pas le constructeur de la classe, car la méthode clone agit directement sur la mémoire. Cela peut entrer en conflit avec des patrons comme le Singleton, où le constructeur est privé, car clone peut contourner cette retsriction.
La distinction entre copie superficielle et copie profonde est cruciale : la méthode clone par défaut ne copie que les types primitifs. Pour les tableaux, collections ou objets référencés, une copie profonde doit être implémentée explictiement. Par exemple :
public class PrototypeComplexe implements Cloneable {
private java.util.List<string> donnees = new java.util.ArrayList<>();
public java.util.List<string> getDonnees() {
return donnees;
}
public void ajouterDonnee(String donnee) {
donnees.add(donnee);
}
@Override
public PrototypeComplexe clone() throws CloneNotSupportedException {
PrototypeComplexe copie = (PrototypeComplexe) super.clone();
copie.donnees = new java.util.ArrayList<>(this.donnees);
return copie;
}
}
</string></string>
En Java, les types primitifs, leurs wrappers et String sont soumis à une copie profonde, tandis que les autres objets nécessitent une gestion manuelle pour éviter les références partagées.