Patrón de prototipo de patrones de diseño comunes en Java

1. Modo de prototipo

El modo de prototipo es un modo de creación de objetos, que se crea copiando a sí mismo.

(1) Características del modelo prototipo

  1. El objeto de destino es creado por el objeto prototipo en sí, es decir, la acción de creación del objeto se envía desde el objeto prototipo en sí.
  2. El objeto de destino es un clon del objeto prototipo. Los objetos creados a través del modo Prottype no solo tienen la misma estructura que el objeto de destino, sino que también tienen el mismo valor que el objeto de destino
  3. Según los diferentes niveles profundos de clonación de objetos, hay clonación superficial y clonación profunda.

En segundo lugar, la realización concreta del modo prototipo.

(1) La diferencia entre clonar y copiar

La clonación se refiere a copiar un objeto de otro objeto con la misma información de objeto, y sus direcciones de memoria son diferentes, y la información del objeto en el montón es la misma pero no la misma; la asignación solo cambia la dirección de memoria entre variables.
Inserte la descripción de la imagen aquí

(2) ¿Cómo lograr la clonación?

  1. Paso 1: implementar la interfaz clonable
  2. Paso 2: reescribe el método clone () en Object
package 原型模式;
//	第一步实现Cloneable接口
public class Student implements Cloneable{
    
    
	private int id;
	private String name;
	private String Sex;
	public int getId() {
    
    
		return id;
	}
	public void setId(int id) {
    
    
		this.id = id;
	}
	public String getName() {
    
    
		return name;
	}
	public void setName(String name) {
    
    
		this.name = name;
	}
	public String getSex() {
    
    
		return Sex;
	}
	public void setSex(String sex) {
    
    
		Sex = sex;
	}
//	重写Object中的clone()方法
	@Override
	protected Student clone() throws CloneNotSupportedException {
    
    
		return (Student) super.clone();
	}
	
}

Llámalo, ¿la clonación es exitosa?

package 原型模式;

public class Maintest {
    
    
	public static void main(String[] args) {
    
    
		System.out.println("      浅度克隆!");
		Student s1 = new Student();
		s1.setId(1);
		s1.setName("张三");
		s1.setSex("男");
		System.out.printf("S1指向内存地址:"+s1+"----");
		System.out.println("S1信息:"+"\tid:"+s1.getId()
		+"\tname:"+s1.getName()+"\tsex"+s1.getSex());
		/* 克隆s1 */
		System.out.println("-----------------------------------------");
		// s1要调用克隆方法
		try {
    
    
			Student s2 = s1.clone();
			System.out.printf("S2指向内存地址:"+s2+"----");
			System.out.println("S2信息:"+"\tid:"+s2.getId()
			+"\tname:"+s2.getName()+"\tsex:"+s2.getSex());
		} catch (CloneNotSupportedException e) {
    
    
			e.printStackTrace();
		}
		
	}
}

** Imprimir información: ** En la información de impresión, puede ver que las direcciones de memoria señaladas por S1 y S2 son diferentes, y la información almacenada en las dos direcciones de memoria es la misma. Esto es un clon, y esto es solo un clon superficial! La superficialidad solo puede lograr la clonación de tipos de datos básicos, pero no
Inserte la descripción de la imagen aquí

Clon profundo

A través del último caso, hemos visto que en la implementación de la clonación superficial, la clonación también es jerárquica. La clonación superficial solo es efectiva para los atributos del tipo de datos básicos, ¡y no tiene efecto sobre el tipo de datos compuestos! Echemos un vistazo al caso, creemos un objeto de Student1, agreguemos un atributo de matriz y luego clonemos el objeto para ver si las direcciones de las matrices son las mismas.

package 原型模式;

import java.util.List;
//第一步实现Cloneable接口
public class Student1 implements Cloneable{
    
    
	private String[] arr = new String[2];
	public String[] getArr() {
    
    
		return arr;
	}
	public void setArr(String[] arr) {
    
    
		this.arr = arr;
	}
	//	重写Object中的clone()方法
	@Override
	protected Student1 clone() throws CloneNotSupportedException {
    
    
		return (Student1) super.clone();
	}	
}

package 原型模式;

import java.util.ArrayList;
import java.util.List;

public class Test {
    
    
public static void main(String[] args) {
    
    
	Student1 s1 = new Student1();
	String[] arr = new String[2];
	arr[0]="数组";
	arr[1]="数据";
	s1.setArr(arr);
	System.out.println("s1地址:"+s1);
	System.out.println("s1数组地址:"+s1.getArr());
	System.out.println("存储信息:"+s1.getArr()[0]+"、"+s1.getArr()[1]);
	
	System.out.println("---------------------------------------------");
	
	try {
    
    
		Student1 s2 = s1.clone();
		System.out.println("s2地址:"+s2);
		System.out.println("s2-集合地址:"+s2.getArr());
		System.out.println("存储信息:"+s2.getArr()[0]+"、"+s2.getArr()[1]);
	} catch (CloneNotSupportedException e) {
    
    
		e.printStackTrace();
	}
}
}

Resultado impreso:
Inserte la descripción de la imagen aquí
Así es
Inserte la descripción de la imagen aquí
como
se implementa la clonación profunda en la memoria , de hecho, cuando reescribimos el método clone (), realizamos la clonación manual y luego regresamos.

package 原型模式;

import java.util.List;
//第一步实现Cloneable接口
public class Student1 implements Cloneable{
    
    
	private String[] arr = new String[2];
	public String[] getArr() {
    
    
		return arr;
	}
	public void setArr(String[] arr) {
    
    
		this.arr = arr;
	}
	//	重写Object中的clone()方法
	@Override
	protected Student1 clone() throws CloneNotSupportedException {
    
    
//		-------------------------实现深度克隆-----------------------
//		先拿到克隆对象
		Student1 student =(Student1)super.clone();
//		然后进行手动克隆,自己进行循环赋值
		
//		先定义一个数组接受
		String[] arr = new String[this.getArr().length];
//		对拷
		for(int i = 0; i < arr.length; i++) {
    
    
			arr[i] = this.getArr()[i];
		}
		student.setArr(arr);
		
		return student;
//		---------------------------------------------------------
	}	
}
package 原型模式;
import java.util.ArrayList;
import java.util.List;
public class Test {
    
    
public static void main(String[] args) {
    
    
	Student1 s1 = new Student1();
	String[] arr = new String[2];
	arr[0]="数组";
	arr[1]="数据";
	s1.setArr(arr);
	System.out.println("s1地址:"+s1);
	System.out.println("s1数组地址:"+s1.getArr());
	System.out.println("存储信息:"+s1.getArr()[0]+"、"+s1.getArr()[1]);
	
	System.out.println("---------------------------------------------");
	
	try {
    
    
		Student1 s2 = s1.clone();
		System.out.println("s2地址:"+s2);
		System.out.println("s2-集合地址:"+s2.getArr());
		System.out.println("存储信息:"+s2.getArr()[0]+"、"+s2.getArr()[1]);
	} catch (CloneNotSupportedException e) {
    
    
		e.printStackTrace();
	}
	
}
}

Inserte la descripción de la imagen aquí

Tres, las ventajas y desventajas del modelo prototipo.

(1) Ventajas del modelo prototipo

  1. Dado que el método de clonación lo ejecuta la máquina virtual copiando directamente el bloque de memoria, es más rápido que usar el nuevo método para crear un objeto.
  2. Cuando la instancia del objeto creado es más compleja, el uso del modo prototipo puede simplificar el proceso de creación del objeto.
  3. El tipo y el estado del objeto se pueden obtener dinámicamente en tiempo de ejecución para crear un objeto.

(2) Desventajas del modelo prototipo

  1. Cada clase debe estar equipada con un método de clonación, y el método de clonación se encuentra en esta clase. Cuando se modifica la clase existente, el código fuente debe modificarse, lo que viola el principio de proporción abierta.
  2. Al implementar la clonación profunda, debe escribir un código más complejo, y cuando hay varias referencias anidadas entre objetos, para lograr una clonación profunda, la clase de cada capa del objeto debe admitir la clonación profunda, que es más problemática de implementar.

Supongo que te gusta

Origin blog.csdn.net/weixin_44676935/article/details/105296180
Recomendado
Clasificación