Modèle prototype
Prototype Pattern est utilisé pour créer des objets répétés tout en garantissant les performances. Ce type de modèle de conception est un modèle de création qui offre une manière optimale de créer des objets.
Ce modèle implémente une interface prototype, qui est utilisée pour créer un clone de l'objet actuel. Ce mode est utilisé lorsque le coût de création directe d'objets est relativement élevé. 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, en renvoyer un clone lors de la prochaine requête et mettre à jour la base de données si nécessaire pour réduire les appels à la base de données.
Introduction
Intention : Utilisez des instances de prototypes pour spécifier les types d'objets à créer et créez de nouveaux objets en copiant ces prototypes.
Solution principale : Créer et supprimer des prototypes pendant l'exécution.
Quand utiliser : 1. Quand un système doit être créé, composé et représenté indépendamment de ses produits. 2. Lorsque la classe à instancier est spécifiée au moment de l'exécution, par exemple via un chargement dynamique. 3. Afin d'éviter de créer une hiérarchie de classes d'usine parallèle à la hiérarchie de classes de produits. 4. Lorsqu'une instance d'une classe ne peut avoir qu'une seule parmi plusieurs combinaisons d'états différentes. Il peut être plus pratique de créer un nombre correspondant de prototypes et de les cloner plutôt que d'instancier manuellement la classe avec l'état approprié à chaque fois.
Comment résoudre : Utilisez un objet prototype existant pour générer rapidement une instance identique à l'objet prototype.
Code clé : 1. Pour implémenter l'opération de clonage, héritez de Cloneable en JAVA et remplacez clone() Dans .NET, vous pouvez utiliser la méthode MemberwiseClone() de la classe Object pour. réaliser le clone superficiel de l'objet ou implémenter une copie profonde via la sérialisation. 2. Le modèle prototype est également utilisé pour isoler la relation de couplage entre les utilisateurs d'objets de classe et des types spécifiques (classes volatiles). Il nécessite également que ces « classes volatiles » aient des interfaces stables.
Exemples d'application : 1. Division cellulaire. 2. Méthode Object clone() en JAVA.
Avantages : 1. Performances améliorées. 2. Échapper aux contraintes du constructeur.
Inconvénients : 1. Equiper la méthode de clonage nécessite une réflexion approfondie sur les fonctions de la classe. Ce n'est pas difficile pour les nouvelles classes, mais ce n'est pas forcément facile pour les classes existantes, surtout quand. Une référence de classe ne prend pas en charge les objets indirects sérialisés ou lorsque la référence contient une structure cyclique. 2. L'interface Cloneable doit être implémentée. 3. Échapper aux contraintes du constructeur.
Scénarios d'utilisation : 1. Scénarios d'optimisation des ressources. 2. L'initialisation de la classe nécessite de digérer beaucoup de ressources, notamment des données, des ressources matérielles, etc. 3. Scénarios avec exigences de performances et de sécurité. 4. Si la génération d'un objet via new nécessite une préparation de données ou des droits d'accès très fastidieux, vous pouvez utiliser le mode prototype. 5. Scénarios avec plusieurs modificateurs d'un objet. 6. Lorsqu'un objet doit être accessible par d'autres objets et que chaque appelant peut avoir besoin de modifier sa valeur, vous pouvez envisager d'utiliser le mode prototype pour copier plusieurs objets à utiliser par l'appelant. 7. Dans les projets réels, le modèle de prototype apparaît rarement seul. Il apparaît généralement avec le modèle de méthode d'usine. Un objet est créé via la méthode clone, puis fourni à l'appelant par la méthode d'usine. Le modèle prototype a été intégré à Java et peut être utilisé par tout le monde.
Remarque : Contrairement à la construction d'un nouvel objet en instanciant une classe, le modèle prototype génère un nouvel objet en copiant un objet existant. La copie superficielle implémente Cloneable, la réécriture et la copie profonde implémente Serialisable pour lire le flux binaire.
Implémentation
Nous allons créer une classe abstraite Shape et une classe d'entité qui étend la classe Shape. L'étape suivante consiste à définir la classe ShapeCache, qui stocke les objets de forme dans une Hashtable et en renvoie des clones sur demande.
PrototypPatternDemo, notre classe de démonstration utilise la classe ShapeCache pour obtenir l'objet Shape.

Étape 1
Créez une classe abstraite qui implémente l'interface Clonable.
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 une classe d'entité qui étend la classe abstraite ci-dessus.
Rectangle.java
public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
Carré.java
public class Square extends Shape { public Square(){ type = "Square"; } @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
Circle.java
public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
Étape 3
Créez une classe pour obtenir les classes d'entités de la base de données et stockez-les dans une Hashtable.
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(); } // 对每种形状都运行数据库查询,并创建该形状 // shapeMap.put(shapeKey, shape); // 例如,我们要添加三种形状 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
PrototypePatternDemo Utilisez la classe ShapeCache pour obtenir le données stockées dans Un clone de la forme dans Hashtable.
PrototypePatternDemo.java
public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Shape : " + 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
Vérifiez la sortie.
Shape : Circle Shape : Square Shape : Rectangle