design pattern (14) - modèles prototypes (le prototype)

définition Concept

Des exemples d'un prototype à créer pour spécifier le type de l'objet, et de créer de nouveaux objets en copiant ce prototype. modèle objet prototype prototype permet un clone (copie) d'une pluralité d'objets qui y identiques, sans avoir à connaître les détails de la façon de créer.

scénarios

  • La création d'objets pour créer plus complexes et nécessitent souvent
  • Il est souhaitable de générer une nouvelle instance selon un exemple classique, par exemple:
    • Quand une large gamme d'objets ne peut pas être intégré dans une classe
    • Quand il est difficile de préciser le nom de la classe générée par l'instance de
    • Des exemples de la trame générée lorsque le découplage souhaités

Dans les applications pratiques, des modèles prototypes se produisent rarement seuls. Souvent mélangé avec d'autres modes.

la mise en œuvre prototype

Toutes les classes héritent de Java java.lang.Object, et la classe Object fournit la méthode clone () à des objets de clone. Par conséquent, la classe Java qui implémente l'interface et réécritures méthode clone Cloneable (), peut être réalisé modèle prototype .

modèle prototype code exemple suivant comme:

// 原型类(也可定义为interface Prototype extends Cloneable)
abstract class Prototype implements Cloneable {
    private String name;
    public void setName(String name) {this.name = name;}
    public String getName() {return this.name;}

    public abstract void doSomething();

    @Override
    public Object clone() { // clone()方法用public修饰
        Object object = null;
        try {
            object = super.clone(); // 调用父类clone()方法
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

// 具体实现类(继承自Prototype类自动具有克隆功能)
class ConcretePrototype extends Prototype{
    public ConcretePrototype() { setName("ConcretePrototype"); }

    @Override
    public void doSomething() { System.out.println("I'll clone myself!"); }
}

public class PrototypeDemo {
    public static void main(String[] args) {
        ConcretePrototype cp = new ConcretePrototype();
        cp.doSomething();

        for(int i=0; i< 5; i++){
            ConcretePrototype cloned = (ConcretePrototype)cp.clone();
            System.out.println("I'm cloned by " + cloned.getName());
        }
    }
}

Après avoir effectué la sortie suivante:

I'll clone myself!
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype

Le mode avantages et inconvénients

modèle prototype avantages suivants:

  • En fonction des besoins du client pour les objets dynamiques pour créer le client d'exécution n'a pas besoin de connaître les détails de la création d'objets, facile à entretenir et développer le code.
  • Lors de la création d'un objet pour créer plus complexe ou répétée un grand nombre d'objets similaires, l'objet est de créer des simplifié et la performance (appellera automatiquement toute la nouvelle chaîne de constructeur, mais ne remet pas de méthode constructeur de classe clone) plus élevé que les nouveaux objets directement .
  • modèle de prototype similaire au mode d'usine, mais il n'y a pas de structure hiérarchique des relations plantes abstraites modèle industriel et le code spécifique à l'usine plus claire et plus simple.

Sont les suivants lacunes:

  • Require () doit être modifié pour chaque classe implémente l'interface Cloneable et remplacer la méthode clone lorsque, en modifiant la classe existante de sa source, contrairement au « principe d'ouverture et de clôture. »
  • Singleton et le modèle d'usine, les modèles prototypes sont en conflit, essayez de ne pas mélanger.
  • Lors de la mise en œuvre d'une copie complète (clone profond) besoin d'écrire du code compliqué.

précautions

Procédé clone () de copier uniquement les types de données de base des objets, sans copier le tableau, l'objet conteneur, la référence d'objet et analogues. Pour obtenir copie en profondeur, vous devez Prototype mode tableau, l'objet conteneur, objet de référence comme une copie distincte .
D' autres objets, par exemple, lorsqu'une copie en profondeur de l'objet, l'objet doit implémenter l' interface Cloneable et méthode clone de substitution (), et l'objet dans la méthode clone de référence () est également un clone. De même, l'objet référencé aussi faire le même processus.
Remarque, Boolean, Byte, caractère, classe , Double, Float, Integer, Long, Short, cordes , et la plupart des sous - classes d'exception sont de classe immuable, il ne faut pas mettre en œuvre une copie en profondeur l'objet. De plus, la plupart des classes de conteneurs Java ont été atteints fonction de clonage.

En revanche, la méthode clone () est plus approprié pour un tableau de copie en profondeur. Mais notez les deux points suivants:

(1) types de base de réseau à une dimension de ces (int[])data.clone()formes de clonage, le type de base du « tableau à deux dimensions » ( en fait, comme un type int [] est une matrice à une dimension) demandé par Wei Kelong. Par exemple:

public static int[][] twoDimensionArrayClone (int[][] tdArray){
    int[][] copy = tdArray.clone();
    for (int i = 0; i < tdArray.length; i++) {
        copy[i] = tdArray[i].clone();
    }
    return copy;
}

(2) Lorsque les éléments du tableau à des objets Java ordinaires, mais aussi le tableau cloné de clone contenu dans le tableau. Les exemples suivants montrent en détail les différentes façons une faible profondeur par rapport profonde copie du tableau d'objets:

class Person implements Cloneable {
    public String name;
    public Person(String name) {this.name = name;}

    @Override
    public Object clone() {
        Object object = null;
        try {
            object = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

public class ArrayPrototype {
    public static void main(String[] args) {
		Person[] origin = new Person[] { new Person("Mike"), new Person("Jack"), new Person("Jason") };
		Person[] copyOf = Arrays.copyOf(origin, origin.length);
		// 浅拷贝(内部调用System.arraycopy,返回新数组)
		Person[] arrayCopy = new Person[origin.length];
		// 浅拷贝(可拷贝部分数组)
		System.arraycopy(origin, 0, arrayCopy, 0, origin.length);
		Person[] clonedCopy = origin.clone();
		// 浅拷贝
		System.out.println("origin=copyOf=arrayCopy=clonedCopy="
				+ (origin[0] == copyOf[0] && copyOf[1] == arrayCopy[1] && arrayCopy[2] == clonedCopy[2]));
		clonedCopy[0].name = "Lily";
		System.out.println("Shallow Person[0]: " + origin[0].name + " -> " + clonedCopy[0].name);

		Person[] deepCopy = new Person[origin.length];
		// 深拷贝
		for (int i = 0; i < origin.length; i++) {
			deepCopy[i] = (Person) origin[i].clone();
		}
		deepCopy[1].name = "Lily";
		System.out.println("Deep Person[1]: " + origin[1].name + " -> " + clonedCopy[1].name);
		Person[] deepCopy2 = Arrays.stream(origin).map(Person::clone).toArray(Person[]::new);
		// 深拷贝
		deepCopy2[2].name = "Lucy";
		System.out.println("Deep Person[2]: " + origin[2].name + " -> " + deepCopy2[2].name);
	}
}

pratiques de l'industrie

  • Objets d'action (Struts2)
  • prototype instance de haricot (printemps) créé
Publié 295 articles originaux · louange gagné 37 · vues 30000 +

Je suppose que tu aimes

Origine blog.csdn.net/tianshan2010/article/details/104722260
conseillé
Classement