English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Explication détaillée de l'exemple de modèle prototype dans la programmation Android

L'exemple présenté dans cet article décrit le modèle de conception prototype en programmation Android. Partageons-le avec vous pour que vous puissiez le consulter, voici les détails:

Un, introduction

Le modèle prototype est un modèle de création. Les deux caractères indiquent que ce modèle devrait avoir un exemple modèle, à partir duquel l'utilisateur peut copier un objet avec des propriétés internes identiques, ce processus est ce que nous appelons couramment «clonage». L'instance copiée est ce que nous appelons le «prototype», ce prototype est également personnalisable. Le modèle prototype est souvent utilisé pour créer des instances complexes ou coûteuses en termes de construction, car dans ce cas, la copie d'une instance existante peut rendre le programme plus efficace.

Deux, la définition

Utiliser un exemple prototype pour spécifier le type d'objet à créer, puis créer de nouveaux objets en copiant ces prototypes.

Trois, les scénarios d'utilisation

(1)L'initialisation de la classe nécessite une consommation de ressources très importante, ces ressources incluent des données, des ressources matérielles, etc., et l'utilisation de la copie prototype évite ces consommations.

(2)La création d'un objet via new nécessite une préparation de données ou des droits d'accès très complexes, dans ce cas, le modèle prototype peut être utilisé.

(3)Un objet doit être fourni à d'autres objets pour l'accès, et chaque appelant peut peut-être modifier sa valeur, dans ce cas, il est envisageable d'utiliser le modèle prototype pour copier plusieurs objets pour les utilisateurs appelants, c'est-à-dire la copie protectrice.

Il convient de noter que, lors de l'appel de la fonction clone pour construire une instance via l'interface Cloneable, cela n'est pas nécessairement plus rapide que l'utilisation de l'opérateur new, à moins que la construction d'un objet via new soit coûteuse en termes de temps ou de coût. Dans ce cas, l'utilisation de la méthode clone peut obtenir une augmentation de l'efficacité. Par conséquent, lors de l'utilisation de Cloneable, il faut considérer le coût de construction de l'objet et effectuer des tests d'efficacité. Bien sûr, l'implémentation du modèle prototype n'a pas besoin de réaliser l'interface Cloneable, il existe d'autres méthodes d'implémentation, et nous allons les expliquer les unes après les autres.

Quatre, le diagramme UML du modèle prototype

Présentation des rôles dans la figure:

Client: utilisateur client.

Prototype: une classe abstraite ou une interface, déclarant la capacité de clonage.

ConcretePrototype: la classe prototype concrète.

Cinq, une simple implémentation du modèle prototype

Pour illustrer le modèle prototype avec un exemple simple de copie de document, nous créons d'abord un objet Document, c'est-à-dire WordDocument, qui contient du texte et des images. Après une longue édition de contenu, l'utilisateur a l'intention de procéder à une édition supplémentaire de ce document, mais il n'est pas encore déterminé si ce document édité sera adopté. Par conséquent, pour des raisons de sécurité, l'utilisateur doit d'abord faire une copie du document actuel, puis procéder aux modifications sur la copie du document. Cela est similaire à la copie protectrice mentionnée dans le livre «Effective Java». De cette manière, le document original est ce que nous appelons l'exemple modèle, c'est-à-dire l'objet à être «cloné», que nous appelons le prototype:

Exemple de code :

/**
 * Type de document, jouant le rôle de ConcretePrototype, tandis que cloneable représente le rôle de prototype.
 */
public class WordDocument implements Cloneable {
 //texte
 private String mText;
 //图片名列表
 private ArrayList<String> mImages = new ArrayList<String>();
 public WordDocument(){
  System.out.println("-------- constructeur de WordDocument --------");
 }
 public String getText(){
  return this.mText;
 }
 public void setText(String text){
  this.mText = text;
 }
 public ArrayList<String> getImages(){
  return this.mImages;
 }
 public void setImages(ArrayList<String> images){
  this.mImages = images;
 }
 public void addImage(String img){
  this.mImages.add(img);
 }
 /**
  * 打印文档
  */
 public void showDocument(){
  System.out.println("-------- Début du contenu du mot --------");
  System.out.println("Text : " + this.mText);
  System.out.println("Images List : ");
  for(String image : mImages){
   System.out.println("image name : " + image);
  }
  System.out.println("-------- Fin du contenu du mot --------");
 }
 @Override
 protected WordDocument clone(){
  try{
   WordDocument doc = (WordDocument)super.clone();
   doc.mText = this.mText;
   doc.mImages = this.mImages;
   return doc;
  }catch(Exception e){}
  return null;
 }
}

执行方法:

public static void main(String[] args) throws IOException {
  //1.构建文档对象
  WordDocument originDoc = new WordDocument();
  //2.编辑文档,添加图片等
  originDoc.setText("这是一篇文档");
  originDoc.addImage("图片一");
  originDoc.addImage("图片二");
  originDoc.addImage("图片三");
  .addImage("C'est une nouvelle image ajoutée");
  //originDoc.addImage("image trois");
  copie une copie en原型 du document original2 WordDocument doc
  doc2originDoc.showDocument();
  //= originDoc.clone();
  doc2modifier la copie du document2.setText("C'est le Doc
  doc2texte");
  .addImage("C'est une nouvelle image ajoutée");
  doc2originDoc.showDocument();
}

.showDocument();

-------- constructeur de WordDocument --------
//originDoc
-------- Début du contenu du mot --------
Texte : c'est un document
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
-------- Fin du contenu du mot --------
//doc2
-------- Début du contenu du mot --------
Texte : c'est un document
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
-------- Fin du contenu du mot --------
//modifié après la copie de originDoc
-------- Début du contenu du mot --------
Texte : c'est un document
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
nom de l'image : c'est une image ajoutée
-------- Fin du contenu du mot --------
//modifié après la copie du document2
-------- Début du contenu du mot --------
Texte : c'est le Doc modifié2texte
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
nom de l'image : c'est une image ajoutée
-------- Fin du contenu du mot --------

résultat de l'exécution :2Nous avons découvert que par la modification de doc

Après cela, il n'a affecté que mImages d'originDoc, sans changer mText.

六、Copie superficielle et copie profonde

l'implémentation réelle du modèle prototype est une copie superficielle, également connue sous le nom de copie d'ombre, cette copie ne recrée pas tous les champs du document original, mais les champs du document de copie référencent les champs du document original, comme indiqué dans le graphique suivant :2a ajouté une image, mais elle est également affichée dans originDoc, comment cela est-il possible ? Les lecteurs attentifs peuvent remarquer que les informations des deux derniers documents sont identiques. Dans doc++les lecteurs auront une expérience très profonde, car dans la méthode clone de WordDocument mentionnée précédemment, une copie superficielle a été effectuée simplement, l'objet de type référence doc2.mImages ne crée pas une nouvelle instance de mImages, mais pointe simplement vers la référence this.mImages, ce qui entraîne que doc2.mImages est un objet partagé avec le document original, donc si l'on modifie une image dans un des documents, l'autre document est également affecté. Alors, comment résoudre ce problème ? La réponse est l'utilisation de la copie profonde, c'est-à-dire, lors de la copie d'un objet, il faut également copier les champs de type référence, et non pas simplement les référencer.

La méthode clone a été modifiée comme suit (les autres restent inchangées) :

@Override
protected WordDocument clone(){
  try{
   WordDocument doc = (WordDocument)super.clone();
   doc.mText = this.mText;
   //Toute appel de la fonction clone() pour l'objet mImages, pour effectuer une copie profonde.
   doc.mImages = (ArrayList<String>)this.mImages.clone();
   return doc;
  }catch(Exception e){}
  return null;
}

Le résultat de l'exécution du code après la modification est :

-------- constructeur de WordDocument --------
//originDoc
-------- Début du contenu du mot --------
Texte : c'est un document
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
-------- Fin du contenu du mot --------
//doc2
-------- Début du contenu du mot --------
Texte : c'est un document
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
-------- Fin du contenu du mot --------
//modifié après la copie de originDoc
-------- Début du contenu du mot --------
Texte : c'est un document
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
-------- Fin du contenu du mot --------
//modifié après la copie du document2
-------- Début du contenu du mot --------
Texte : c'est le Doc modifié2texte
Liste des images :
nom de l'image : image un
nom de l'image : image deux
nom de l'image : image trois
nom de l'image : c'est une image ajoutée
-------- Fin du contenu du mot --------

Il est évident que maintenant ils ne se influencent pas mutuellement, ce qui s'appelle une copie profonde.

En répondant à la question précédente, en fait, le type String, lors de la copie shallow, est semblable aux types de référence, sans copie distincte, mais il fait référence à la même adresse, car String n'a pas réalisé l'interface cloneable, ce qui signifie qu'il ne peut copier que les références. (Nous pouvons voir cela dans le code source, tandis que ArrayList a réalisé l'interface cloneable). Mais lorsque nous modifions l'une des valeurs, une nouvelle mémoire est allouée pour stocker la nouvelle valeur, et cette référence pointe vers cette nouvelle mémoire. Le String original, car il existe encore des références qui le pointent, n'est pas recyclé. Ainsi, bien que ce soit une copie de la référence, la modification de la valeur ne change pas la valeur de l'objet copié.

Par conséquent, dans de nombreux cas, nous pouvons traiter String de la même manière que les types de base lors de la clonage, mais nous devons simplement noter certaines choses lors de l'utilisation de equals.

Le modèle prototype est très simple, et son problème central est de copier l'objet original. Un point à noter lors de l'utilisation de ce modèle est que le problème des copies profondes et shallows doit être pris en compte. Pendant le développement, pour réduire les erreurs, l'auteur recommande d'utiliser la copie profonde plutôt que la copie shallow pour éviter que les opérations sur les copies affectent l'objet original.

Sept, le modèle prototype dans le code source d'Android

Exemple de code :

Uri uri = Uri.parse("smsto:");110");
Intent intent = new Intent(Intent.ACTION_SEND,uri);
intent.putExtra("sms_body", "The SMS text");
//clonage
Intent intent2 = (Intent)intent.clone();
startActivity(intent2);

Huit, résumé

Le modèle prototype est essentiellement une copie d'objet, et il est similaire à C++Les constructeurs de copie de l'objet sont quelque peu similaires, et les problèmes courants qu'ils peuvent rencontrer sont tous liés aux copies profondes et shallows. L'utilisation du modèle prototype peut résoudre le problème de la consommation de ressources lors de la construction d'objets complexes et peut améliorer l'efficacité de la création d'objets dans certains scénarios.

Avantages :

(1Le patron de conception Prototype est une copie en binaire en mémoire, ce qui est beaucoup plus performant que la création directe d'un objet new, en particulier lorsque de nombreux objets doivent être générés dans une boucle, le patron de conception Prototype peut mieux illustrer ses avantages.

(2La copie de protection est également une application importante, c'est-à-dire que pour un objet externe qui peut être seulement lu, pour éviter que l'extérieur modifie cet objet lecture seule, il est généralement possible de réaliser la restriction de lecture seule en retournant une copie de l'objet.

Faiblesse :

(1La copie directe en mémoire est à la fois une force et une faiblesse. Le constructeur n'est pas exécuté, ce qui doit être pris en compte dans le développement réel. Les avantages sont que les contraintes sont réduites, mais les inconvénients sont également que les contraintes sont réduites, nécessitant que les utilisateurs considèrent ces contraintes dans leurs applications réelles.

(2La mise en œuvre du patron de conception Prototype en implémentant l'interface Cloneable ne signifie pas nécessairement que l'appel de la fonction clone pour construire des instances est plus rapide que l'utilisation de l'opérateur new, à moins que la construction d'objets par new soit particulièrement coûteuse ou coûteuse en termes de temps. Seulement dans ce cas, la méthode clone peut obtenir une augmentation de l'efficacité.

Pour ceux qui sont intéressés par plus de contenu sur Android, vous pouvez consulter les sujets spéciaux de ce site : "Introduction et avancement des tutoriels de développement Android", "Conseils de débogage et solutions de problèmes courants pour Android", "Résumé des utilisations des composants de base d'Android", "Résumé des techniques des vues View d'Android", "Résumé des techniques des layouts layout d'Android" et "Résumé des utilisations des contrôles d'Android".

Nous espérons que les informations fournies dans cet article vous seront utiles pour la conception de programmes Android.

Déclaration : Le contenu de cet article est issu du réseau, propriété de ses auteurs respectifs, le contenu est apporté par les utilisateurs d'Internet et téléchargé spontanément. Ce site ne détient pas de propriété, n'a pas été édité par l'homme, et ne assume aucune responsabilité juridique. Si vous trouvez du contenu susceptible de violer les droits d'auteur, vous êtes invité à envoyer un e-mail à : notice#w3Déclaration : Le contenu de cet article est issu du réseau, propriété de ses auteurs respectifs, le contenu est apporté par les utilisateurs d'Internet et téléchargé spontanément. Ce site ne détient pas de propriété, n'a pas été édité par l'homme, et ne assume aucune responsabilité juridique. Si vous trouvez du contenu susceptible de violer les droits d'auteur, vous êtes invité à envoyer un e-mail à : notice#w

Vous pourriez aussi aimer