Questions sur le modèle de prototype

J’apprends les différents modèles de conception et j’ai le sentiment fort que je manque une pièce (ou des pièces) essentielle (s) pour comprendre ce modèle particulier.

Dans tous les sites Web que j’ai consultés et dans le livre GoF, je vois la méthode des clones. D’après ce que j’ai compris, nous avons un type d’object que nous pouvons cloner lorsque nous avons besoin de différentes versions de cet object, mais nous ne voulons pas avoir à les créer manuellement à l’aide de la nouvelle commande (comme en Java). Cela peut cacher sa mise en œuvre concrète. Ainsi, lorsque nous clonons, nous pouvons modifier un peu le clone et en faire ce dont nous avons besoin sans avoir à savoir comment créer à l’origine cet object à la dure. Est-ce que ma pensée est correcte?

On me dit également que cela peut réduire le sous-classement et, par la suite, réduire le nombre de cours à effectuer. Je ne comprends pas bien cette partie. Quelqu’un pourrait-il m’aider à comprendre cela?

Ma dernière question concerne le modèle de l’usine abstraite (ou même de la méthode d’usine). Ces modèles d’usine et le modèle de prototype donnent l’impression de tenter de cacher des implémentations concrètes lors de la création de nouveaux objects. Quand est-ce une bonne idée de choisir l’un de l’autre?

Merci à tous!

Modèle de prototype

Le prototype produit un object cloné différent de l’object d’origine. L’état de l’original est le même que celui du clone, au moment du clonage. Par la suite, chaque object peut subir un changement d’état. Vous pouvez penser à ceci comme quelque chose de similaire en photocopiant l’original et en modifiant ensuite la photocopie à quelques endroits.

Exemple

  • DVD duplication: duplication du dvd master pour créer plusieurs copies
  • Objet de rapport: considérez un object de rapport contenant des informations traitées à transmettre à l’interface graphique. Le rapport d’origine contient les données en ordre croissant. Maintenant, en utilisant ce modèle, on peut créer un rapport similaire, mais avec des données sortingées par ordre décroissant.

Avantages

  • Performance: le clonage (à l’aide de MemberwiseClone ) est considérablement moins coûteux que la création d’un nouvel object (avec un nouvel opérateur ). Notez qu’il faut remplacer le MemberwiseClose() pour effectuer une copie MemberwiseClose() .
  • Les objects peuvent être clonés de manière très dynamic, sans aucune insistance sur l’instanciation initiale. Le premier object créé peut être créé à tout moment dans l’exécution de l’application, et une duplication supplémentaire peut avoir lieu à tout moment.

Quand l’utiliser

  • Lorsque les classes à instancier sont spécifiées lors de l’exécution, par exemple, par chargement dynamic.
  • Lorsque les instances d’une classe peuvent avoir l’une des quelques combinaisons d’états différentes. Il peut être plus pratique d’installer un nombre correspondant de prototypes et de les cloner plutôt que d’instancier manuellement la classe, chaque fois avec l’état approprié.

Comparaison avec le modèle d’usine

Le modèle de prototype permet à un object de créer des objects personnalisés sans connaître leur classe ou des détails sur leur création. Donc, c’est cet aspect qui ressemble beaucoup au modèle de méthode d’usine. Dans ces deux modèles, le client peut créer n’importe lequel des objects de classe dérivés sans rien savoir de leur propre structure.

Mais la différence entre les deux modèles réside dans le fait que la Factory Method concentre sur la création d’un object d’un type d’object non existant en tant que fresh creation (en comprenant le sous-type exact de la classe Creator). Le modèle Prototype utilise la classe elle-même, en particulier la classe dérivée pour self duplication action de self duplication .

Modèle de méthode d’usine

Dans ce modèle, le client (ou le consommateur) demande au créateur (ou à la fabrique) un type d’object spécifique dans une hiérarchie de classes. La méthode Creator de la classe de fabrique délègue la création de l’object spécifique aux classes dérivées et renvoie l’object de la classe du type demandé par le client. Essentiellement, vous avez un seul sharepoint contact pour la création de plusieurs objects d’une hiérarchie de classes.

Vous pouvez envisager cela comme aller à un guichet de billets d’avion (contrôleur) et demander un billet en donnant votre préférence du type de billet (première classe, exécutif ou économique). L’utilisateur n’est pas concerné par la manière dont le ticket est généré, même si, dans une représentation d’object, la première classe et le ticket économique sont tous deux dérivés de la classe de ticket de base.

Quand utiliser

  • La flexibilité est importante (faible couplage)
  • Les objects peuvent être étendus dans des sous-classes
  • Il existe une raison spécifique pour laquelle une sous-classe serait choisie par rapport à une autre – cette logique fait partie de la méthode Factory.
  • Un client délègue des responsabilités à des sous-classes dans des hiérarchies parallèles.

Motif d’usine abstrait

L’usine abstraite va plus loin (plus abstraite) que le modèle de méthode d’usine. Dans ce cas, on peut avoir non seulement une seule, mais plusieurs usines avec de légères variations. Il est responsable de la création d’objects appartenant à des familles de hiérarchies de classes plutôt que d’une hiérarchie de classes unique.

Une classe Factory spécifique existe déjà. Mais l’usine aura des méthodes légèrement différentes. Chaque méthode peut produire une instance. Le client peut choisir la méthode appropriée et obtenir l’instance.

Si vous prenez l’exemple de la conception architecturale parfaite basée sur MVC , le client sera une classe de contrôleur de gestion tandis que les produits concrets seront tous des entités commerciales. Les usines sont des contrôleurs auxiliaires (auxiliaires). Ils travaillent en association avec une demande du contrôleur de gestion.

Quand utiliser

  • Le système devrait être indépendant de la façon dont les produits sont créés. Il peut même s’attendre à une indépendance sur la composition et la représentation des produits. Le terme produit s’applique à l’object final qu’un développeur client doit utiliser en invoquant ses méthodes.
  • Le système devant être configurable avec l’une des nombreuses familles de produits. La sélection de la famille ne se fera donc pas au moment du codage, mais à une heure de configuration ultérieure.
  • La famille de produits est conçue pour fonctionner toujours ensemble.
  • La création est pour une bibliothèque de produits. Ce qui est plus concerné ici, c’est l’interface pertinente et non l’implémentation.

Vous avez le modèle de prototype par l’apparence de celui-ci.

Comment cela réduit le sous-classement

Disons que vous fabriquez MineCraft et que vous utilisez le modèle de prototype pour chaque type de bloc (par exemple, la saleté, la pierre, etc.). Tous les objects prototypes sont en fait de la même classe Block , mais chaque object a des propriétés différentes, de sorte qu’il ressemble et se comporte différemment, par exemple:

 prototypes.dirt = new Block; prototypes.dirt.texture = new Image("dirt.jpg"); prototypes.dirt.hardness = 1; prototypes.stone = new Block; prototypes.stone.texture = new Image("stone.jpg"); prototypes.stone.hardness = 9; 

Ainsi, au lieu de sous- new DirtBlock où vous new DirtBlock ou un new StoneBlock , vous écrivez plutôt prototypes.dirt.clone() ou prototypes.stone.clone() . Aucun sous-classement n’est requirejs, mais vous avez toujours la possibilité de sous-classer le cas échéant.

Différences avec le modèle d’usine

En ce qui concerne le choix du modèle de prototype au lieu du modèle d’usine, il existe deux situations auxquelles je peux penser:

  1. Vous pouvez parcourir une liste de prototypes, mais vous ne pouvez pas parcourir toutes les méthodes d’une fabrique abstraite ^. En continuant avec le code ci-dessus, vous pouvez créer un bloc aléatoire comme ceci:

    prototypes.allValues().objectAtIndex(rand() % prototypes.size()).clone();

    Si vous utilisiez la méthode d’usine pour créer des blocs, il serait plus difficile d’obtenir un bloc aléatoire.

  2. Lorsque la création d’un object est coûteuse, mais que la copie est peu coûteuse, le modèle prototype sera plus efficace. Par exemple, prenez cette méthode d’usine:

     Image loadUserImage() { //loads from disk. will be slow return new JPEGImage("path/to/user/image.jpg"); } 

    Si cette méthode doit être appelée à plusieurs resockets, il serait plus efficace d’utiliser un prototype comme celui-ci:

     Image loadUserImage() { //copy in memory. will be fast return userImagePrototype.clone(); } 

^ C’est un mensonge parce que vous pouvez réellement parcourir les méthodes en fonction de la langue que vous utilisez, mais l’itération sur un tableau est probablement une meilleure solution car elle est moins complexe que la reflection / introspection.

Le gain d’efficacité d’utilisation d’un prototype est discutable dans mon esprit. Il n’y aura pas de gain d’efficacité car dans la plupart des langages, la méthode clone elle-même exécute un appel à new afin de construire une nouvelle instance d’object.

Le seul avantage que je vois en utilisant le modèle de prototype est celui de la commodité, vous savez que clone vous donnera une copie exacte de l’object, ce qui vous évite de définir vous-même les atsortingbuts du nouvel object et peut-être des difficultés avec copie profonde.