patrón de diseño (14) - patrones prototipo (Prototipo)

definición de conceptos

Los ejemplos de un prototipo para ser creados para especificar el tipo de objeto, y para crear nuevos objetos copiando este prototipo. Prototipo modelo de objetos prototipo permite un clon (copia) una pluralidad de objetos idénticas a la misma, sin tener que conocer ningún detalle de cómo crear.

escenarios

  • La creación de objetos para crear más complejo y requiere frecuentes
  • Es deseable generar una nueva instancia de acuerdo con un ejemplo convencional, por ejemplo:
    • Cuando una amplia gama de objetos no se puede integrar en una clase
    • Cuando es difícil de especificar el nombre de la clase generada por la instancia de
    • Ejemplos de la trama generada cuando el deseados desacoplamiento

En las aplicaciones prácticas, modelos de prototipo rara vez se producen solo. A menudo mezclado con otros modos.

prototipo de aplicación

Todas las clases heredan de Java java.lang.Object, y la clase de objeto proporciona método clone () para objetos clon. Por consiguiente, la clase de Java que implementa la interfaz y reescrituras clon Cloneable () método, se puede realizar patrón Prototype .

patrón Prototype código de ejemplo como sigue:

// 原型类(也可定义为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());
        }
    }
}

Después de realizar el siguiente resultado:

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

El modo de ventajas y desventajas

patrón Prototype siguientes ventajas:

  • Dependiendo de los requisitos del cliente para objetos dinámicos para crear en tiempo de ejecución cliente no necesita conocer los detalles de los objetos que crean, fácil de mantener y expandir código.
  • Al crear un objeto para crear más complejo o repetida de un gran número de objetos similares, el objeto es crear simplificado, y el rendimiento (llamará automáticamente toda la nueva cadena de constructor, pero no llama a cualquier método de clase clon constructor) más alta que los nuevos objetos directamente .
  • patrón prototipo similar al modo de fábrica, pero no hay una estructura jerárquica de relaciones abstractas plantas modelo de fábrica y el código específico de la planta más clara y sencilla.

Las deficiencias son las siguientes:

  • Requerir () debe ser modificada para cada interfaz Cloneable implementa la clase y reemplazar el método clon cuando, mediante la alteración de la clase existente de su fuente, en contra de la "principio de apertura y cierre."
  • Singleton y modelo de fábrica, modelos del prototipo están en conflicto, trate de no mezclar.
  • Al implementar una necesidad copia profunda (clon de profundidad) para escribir código complicado.

precauciones

clone () método de copiar sólo los tipos de datos básicos de los objetos, sin copiar la matriz, el objeto contenedor, la referencia de objeto y similares. Para lograr copia profunda, debe Prototipo modo de matriz, el objeto contenedor, objeto de referencia como una copia separada .
Otros objetos, por ejemplo, cuando una copia en profundidad del objeto, el objeto debe implementar la interfaz Cloneable y método clon de anulación (), y el objeto dentro del método clon de referencia () también es un clon. Del mismo modo, el objeto referenciado también hacer el mismo proceso.
Nota, Boolean, Byte, carácter, clase , Double, Float, Integer, Long, Short, cuerdas , y la mayoría de las subclases de excepción son de clase inmutable, no es necesario implementar una copia en profundidad del objeto. Además, la mayoría de las clases de contenedores de Java se han logrado función de clonación.

En contraste, el método clone () es más adecuado para una gran variedad de copia profunda. Pero tenga en cuenta los dos puntos siguientes:

(1) tipos básicos de matriz unidimensional de tales (int[])data.clone()formas de clonación, el tipo básico de "matriz de dos dimensiones" (en realidad, como un tipo int [] es una matriz unidimensional) requerida por Wei Kelong. Por ejemplo:

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) Cuando los elementos de la matriz a objetos Java ordinarias, sino también la matriz clon clonado contenidas en la matriz. Los siguientes ejemplos muestran en detalle las diferentes formas en que un poco profundas vs. profunda copia de la matriz de objetos:

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);
	}
}

prácticas de la industria

  • Objetos de acción (Struts2)
  • instancia del bean (primavera) prototipo creado
Publicados 295 artículos originales · ganado elogios 37 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/tianshan2010/article/details/104722260
Recomendado
Clasificación