您的位置:首页 > 编程语言 > Java开发

java 设计模式之原型模式(浅复制深复制)

2018-02-01 23:29 429 查看
概念:

原形模式:

原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.

原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.

原型模式中的拷贝分为"浅拷贝"和"深拷贝":

浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.

深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.

演示:

package com.dairuijie.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
* 原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个
对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对。在 Java 中,复制对象是通过 clone()实现的
实现深复制需要实现Serializable 可以序列化 不然没法序列化对象去进行流的输入输出
* @author DRJYY
*
*/
public class Prototype implements   Cloneable,Serializable{

/**
*
*/
private static final long serialVersionUID = 1L;
private Integer age;
private String name;

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

/**
* 浅复制
*/
@Override
protected Object clone() throws CloneNotSupportedException {
/*	Prototype prot = (Prototype) super.clone();
return prot;*/
return super.clone();
}

/**
* 深复制
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public Object deepClone() throws IOException, ClassNotFoundException{
/**
*  写入当前对象的二进制流
*/
ByteArrayOutputStream bos =  new ByteArrayOutputStream();
ObjectOutputStream oos =  new ObjectOutputStream(bos);
oos.writeObject( this );

/**
* 写出当前对象二进制流
*/
ByteArrayInputStream bis =  new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois;
ois = new ObjectInputStream(bis);
return ois.readObject();
}

public Prototype(Integer age, String name) {
this.age = age;
this.name = name;
}

}

package com.dairuijie.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* 学生实体类 除了基本数据类型 同时包括Prototype 引用 方便我们测试结果
* @author DRJYY
*
*/
public class Student  implements Cloneable,Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer age;
private String name;
private Prototype prototype;

public Prototype getPrototype() {
return prototype;
}
public void setPrototype(Prototype prototype) {
this.prototype = prototype;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Student(Integer age, String name, Prototype prototype) {
this.age = age;
this.name = name;
this.prototype = prototype;
}
public Object deepClone() throws IOException, ClassNotFoundException{
/**
*  写入当前对象的二进制流
*/
ByteArrayOutputStream bos =  new ByteArrayOutputStream();
ObjectOutputStream oos =  new ObjectOutputStream(bos);
oos.writeObject( this );

/**
* 写出当前对象二进制流
*/
ByteArrayInputStream bis =  new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois;
ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
package com.dairuijie.prototype;

import java.io.IOException;

/**
*
* @author DRJYY
*
*/
public class ShallowTest {
public static void main(String[] args) throws ClassNotFoundException, IOException {
Prototype p = new Prototype(12, "dai");
Student student = new Student(13, "dai", p);
Student stu =	(Student) student.deepClone();
stu.getPrototype().setAge(123);
stu.setAge(11);
System.out.println("原始的student的年龄----"+student.getAge());
System.out.println("克隆对象----"+stu.getAge());
System.out.println("克隆对象中的p 引用---"+stu.getPrototype().getAge());
System.err.println("p的对象原始----"+p.getAge());
}
}


package com.dairuijie.prototype;

public class DeepTest {
public static void main(String[] args) throws CloneNotSupportedException {
Prototype p = new Prototype(12, "dai");
Student student = new Student(13, "dai", p);
Student stu =	(Student) student.clone();
stu.getPrototype().setAge(123);
stu.setAge(11);
System.out.println("原始的student的年龄----"+student.getAge());
System.out.println("克隆对象----"+stu.getAge());
System.out.println("克隆对象中的p 引用---"+stu.getPrototype().getAge());
System.err.println("p的对象原始----"+p.getAge());
}
}


图一  :                                                                                  图二:






如图一就是浅复制结果 发现p 的对象年龄没有变化,图二深复制中p 的对象年龄却被身体stu.getPrototype().setAge(123) 改变了。说明深复制将引用对象都复制过来了。也就是对引用类型的成员变量也进行引用对象的复制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: