Patrons de conception/Prototype
Le patron de conception prototype est utilisé lorsque la création d'une instance est complexe ou consommatrice en temps. Plutôt que créer plusieurs instances de la classe, on copie la première instance et on modifie la copie de façon appropriée.
Pour implanter ce patron il faut déclarer une classe abstraite spécifiant une méthode abstraite (virtuelle pure en C++) appelée "clone()".
Toute classe nécessitant un constructeur polymorphique dérivera de cette classe abstraite et implantera la méthode "clone()".
Le client de cette classe, au lieu d'écrire du code invoquant directement l'opérateur "new" sur une classe explicitement connue, appellera la méthode "clone()" sur le prototype ou passera par un mécanisme fourni par un autre patron de conception (par exemple une méthode de fabrique avec un paramètre désignant la classe concrète à instancier).
Structure.
Le diagramme UML de classes est le suivant :
La classe "Prototype" sert de modèle principal pour la création de nouvelles copies.
Les classes "PrototypeA" et "PrototypeB" viennent spécialiser la classe "Prototype" en venant par exemple modifier certains attributs.
La méthode "clone()" doit retourner une copie de l'objet concerné.
Les sous-classes peuvent hériter ou surcharger la méthode "clone()".
La classe utilisatrice va se charger d'appeler les méthodes de clonage de la classe "Prototype".
Exemple de code en C#.
public enum RecordType
 Car,
 Person
/// <summary>
/// Record est le Prototype
/// </summary>
public abstract class Record
 public abstract Record Clone();
/// <summary>
/// PersonRecord est un Prototype concret
/// </summary>
public class PersonRecord : Record
 string name;
 int age;
 public override Record Clone()
 return (Record)this.MemberwiseClone(); // copie membre à membre par défaut
/// <summary>
/// CarRecord est un autre Prototype concret
/// </summary>
public class CarRecord : Record
 string carname;
 Guid id;
 public override Record Clone()
 CarRecord clone = (CarRecord)this.MemberwiseClone(); // copie membre à membre par défaut
 clone.id = Guid.NewGuid(); // générer un nouvel identifiant unique pour la copie
 return clone;
/// <summary>
/// RecordFactory est la classe utilisatrice
/// </summary>
public class RecordFactory
 private static Dictionary<RecordType, Record> _prototypes = new Dictionary<RecordType, Record>();
 /// <summary>
 /// Constructeur
 /// </summary>
 public RecordFactory()
 _prototypes.Add(RecordType.Car, new CarRecord());
 _prototypes.Add(RecordType.Person, new PersonRecord());
 /// <summary>
 /// Méthode de fabrication
 /// </summary>
 public Record CreateRecord(RecordType type)
 return _prototypes[type].Clone();
Exemple de code en JAVA.
/* Classe Prototype */
public class Cookie implements Cloneable
 public Cookie clone()
 try {
 Cookie copy = (Cookie)super.clone();
 // Dans une implémentation réelle de ce patron de conception, il faudrait
 // créer la copie en dupliquant les objets contenus et en attribuants des
 // valeurs valides (exemple : un nouvel identificateur unique pour la copie).
 return copy;
 } catch (CloneNotSupportedException e) {
 return null;
/* Prototype concrets à copier */
/* Classe utilisatrice */
public class CookieMachine
 private Cookie cookie; // peut aussi être déclaré comme : private Cloneable cookie;
 public CookieMachine(Cookie cookie)
 this.cookie = cookie; 
 public Cookie makeCookie()
 return cookie.clone(); 
 public static void main(String args[])
 Cookie tempCookie = null; 
 Cookie prot = new CoconutCookie(); 
 CookieMachine cm = new CookieMachine(prot); 
 for (int i=0; i<100; i++)
 tempCookie = cm.makeCookie(); 
Exemples.
Exemple où prototype s'applique : supposons une classe pour interroger une base de données.
À l'instanciation de cette classe on se connecte et on récupère les données de la base avant d'effectuer tous types de manipulation.
Par la suite, il sera plus performant pour les futures instances de cette classe de continuer à manipuler ces données que de réinterroger la base.
Le premier objet de connexion à la base de données aura été créé directement puis initialisé.
Les objets suivants seront une copie de celui-ci et donc ne nécessiteront pas de phase d'initialisation.