Patron Prototype

Le patron Prototype est utilisé pour créer des objets dupliqués tout en garantissant les performances. Ce type de patron de conception appartient aux patrons de création, et il fournit l'une des meilleures façons de créer des objets.

Ce patron implémente une interface prototype, qui est utilisée pour créer un clone de l'objet courant. Ce patron est utilisé lorsque la création directe d'un objet est relativement coûteuse. Par exemple, un objet doit être créé après une opération de base de données coûteuse. Nous pouvons mettre l'objet en cache, renvoyer son clone lors de la prochaine requête, et mettre à jour la base de données lorsque nécessaire, ce qui réduit les appels à la base de données.

summary

Patron Prototype

Intention: Utiliser des instances de prototype pour spécifier les types d'objets à créer, et créer de nouveaux objets en copiant ces prototypes.

Principaux problèmes résolus: Créer et supprimer dynamiquement des prototypes à l'exécution.

Quand l'utiliser

  • Le système doit être indépendant de la création, de la composition et de la représentation des produits.
  • La classe à instancier doit être spécifiée au moment de l'exécution, par exemple par chargement dynamique.
  • Éviter de créer une hiérarchie de classes de fabriques parallèle à la hiérarchie de classes de produits.
  • Les instances d'une classe ne peuvent avoir que quelques combinaisons d'états différentes ; le clonage d'un prototype est plus pratique que l'instanciation manuelle.

Comment résoudre

Générer rapidement une instance identique à l'objet prototype en utilisant un objet prototype existant.

Code clé

  • Implémenter l'opération de clonage :
    • En Java, implémenterCloneableInterface, overrideclone()méthode.
    • En .NET, utiliserObjectClasseMemberwiseClone()La méthode implémente une copie superficielle, ou une copie profonde via la sérialisation.
  • Isoler le couplage entre les utilisateurs d'objets de classe et les types concrets, en exigeant que les "classes volatiles" aient des interfaces stables.

Exemple d'application

  • Division cellulaire
  • En JavaObject.clone()Méthodes

Avantages

  • Amélioration des performances
  • Éviter les contraintes du constructeur

Inconvénients

  • Équiper une classe de méthodes clone exige une prise en compte exhaustive de la fonctionnalité de la classe, ce qui peut être difficile pour des classes existantes, en particulier lorsqu'il s'agit d'objets indirects qui ne prennent pas en charge la sérialisation ou de références contenant des structures circulaires.
  • Doit être implémentéCloneableInterface.

Cas d'utilisation

  • Optimisation des ressources
  • Lorsque l'initialisation d'une classe consomme une grande quantité de ressources (telles que des données, des ressources matérielles).
  • Scénarios avec des exigences élevées en matière de performances et de sécurité
  • VianewLorsque la création d'un objet nécessite une préparation complexe des données ou des autorisations d'accès.
  • Un objet nécessite plusieurs modificateurs
  • Lorsqu'un objet doit être fourni à d'autres objets pour qu'ils y accèdent et qu'il peut être modifié par divers appelants.
  • Il est souvent utilisé conjointement avec le patron de méthode de fabrique, viaclonela création d'objets, qui sont ensuite fournis aux appelants par la méthode de fabrique.

Notes

Contrairement à l'instanciation directe d'une classe pour créer un nouvel objet, le modèle Prototype génère de nouveaux objets en copiant des objets existants. La copie superficielle est réalisée en implémentantCloneabletandis que la copie profonde est réalisée en implémentantSerializablela lecture de flux binaires.

Structure

Le modèle prototype comprend les rôles principaux suivants :

  • Interface Prototype: Définit une interface pour se cloner elle-même, incluant généralement uneclone()méthode.

  • Prototype Concret: Une classe concrète qui implémente l'interface prototype et est responsable de l'opération de clonage réelle. Cette classe doit implémenter laclone()méthode, en utilisant généralement une copie superficielle ou une copie profonde pour se copier elle-même.

  • Client: Utilise des instances de prototype pour créer de nouveaux objets. Le client appelle laclone()méthode pour créer de nouveaux objets au lieu d'utiliser directement les constructeurs.

Implémentation

Nous allons créer une classe abstraiteShapeet étendreShapeclasses concrètes de la classe. L'étape suivante consiste à définir la classeShapeCache, cette classe stocke les objets de forme dans uneHashtableet renvoie leurs clones lorsqu'ils sont demandés.

PrototypePatternDemoClasse utiliseShapeCacheclasse pour obtenirShapeObjet.

原型模式的 UML 图

Étape 1

Créez une classe abstraite quiCloneableimplémente l'interface.

Shape.java

public abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType(){ return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } }

Étape 2

Créez des classes d'entités qui étendent la classe abstraite ci-dessus.

Rectangle.java

public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("À l'intérieur de la méthode Rectangle::draw()."); } }

Square.java

public class Square extends Shape { public Square(){ type = "Square"; } @Override public void draw() { System.out.println("À l'intérieur de la méthode Square::draw()."); } }

Circle.java

public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("À l'intérieur de la méthode Circle::draw()."); } }

Étape 3

Créez une classe qui récupère des classes d'entités depuis une base de données et les stocke dans uneHashtableDans.

ShapeCache.java

import java.util.Hashtable; public class ShapeCache { private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } //Exécutez une requête de base de données pour chaque forme et créez cette forme // shapeMap.put(shapeKey, shape); //Par exemple, nous voulons ajouter trois formes public static void loadCache() { Circle circle = new Circle(); circle.setId("1"); shapeMap.put(circle.getId(),circle); Square square = new Square(); square.setId("2"); shapeMap.put(square.getId(),square); Rectangle rectangle = new Rectangle(); rectangle.setId("3"); shapeMap.put(rectangle.getId(),rectangle); } }

Étape 4

PrototypePatternDemoUtilisationShapeCacheclasse pour obtenir le prototype stocké dansHashtablele clone de la forme à l'intérieur.

PrototypePatternDemo.java

public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Forme : " + clonedShape.getType()); Shape clonedShape2 = (Shape) ShapeCache.getShape("2"); System.out.println("Shape : " + clonedShape2.getType()); Shape clonedShape3 = (Shape) ShapeCache.getShape("3"); System.out.println("Shape : " + clonedShape3.getType()); } }

Étape 5

Exécutez le programme, résultat de sortie :

Shape : Circle
Shape : Square
Shape : Rectangle
autres extensions