Si vous disposez d'ouvrages ou d'articles de référence ou si vous connaissez des sites web de qualité traitant du thème abordé ici, merci de compléter l'article en donnant les références utiles à sa vérifiabilité et en les liant à la section « Notes et références ».
En programmation informatique, le patron de conceptionprototype 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 implémenter ce patron il faut déclarer une classe abstraite spécifiant une méthode virtuelle pure appelée clone(). Toute classe nécessitant un constructeurpolymorphique dérivera de cette classe abstraite et implémentera 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).
La classe Prototype sert de modèle principal pour la création de nouvelles copies. Les classes ConcretePrototype1 et ConcretePrototype2 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 Client va se charger d'appeler les méthodes de clonage via sa méthode operation().
Exemple de code en C#
publicenumRecordType{Car,Person}/// <summary>/// Record is the Prototype/// </summary>publicabstractclassRecord:ICloneable{#region ICloneable MembresobjectICloneable.Clone(){returnthis.Clone();}#endregionpublicabstractRecordClone();}/// <summary>/// PersonRecord is the Concrete Prototype/// </summary>publicclassPersonRecord:Record{stringname;intage;publicoverrideRecordClone(){return(Record)this.MemberwiseClone();// default shallow copy}}/// <summary>/// CarRecord is another Concrete Prototype/// </summary>publicclassCarRecord:Record{stringcarname;Guidid;publicoverrideRecordClone(){CarRecordclone=(CarRecord)this.MemberwiseClone();// default shallow copyclone.id=Guid.NewGuid();// always generate new idreturnclone;}}/// <summary>/// RecordFactory is the client/// </summary>publicclassRecordFactory{privatestaticDictionary<RecordType,Record>_prototypes=newDictionary<RecordType,Record>();/// <summary>/// Constructor/// </summary>publicRecordFactory(){_prototypes.Add(RecordType.Car,newCarRecord());_prototypes.Add(RecordType.Person,newPersonRecord());}/// <summary>/// The Factory method/// </summary>publicRecordCreateRecord(RecordTypetype){return_prototypes[type].Clone();}}
Exemple de code en JAVA
/* Prototype Class */publicclassCookieimplementsCloneable{@OverridepublicCookieclone(){try{Cookiecopy=(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 attribuant des// valeurs valides (exemple : un nouvel identificateur unique pour la copie).returncopy;}catch(CloneNotSupportedExceptione){returnnull;}}}/* Concrete Prototypes to clone */publicclassCoconutCookieextendsCookie{}/* Client Class */publicclassCookieMachine{privateCookiecookie;// aurait pu être "private Cloneable cookie;"publicCookieMachine(Cookiecookie){this.cookie=cookie;}publicCookiemakeCookie(){returncookie.clone();}publicstaticvoidmain(Stringargs[]){CookietempCookie=null;Cookieprot=newCoconutCookie();CookieMachinecm=newCookieMachine(prot);for(inti=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.