原型模式(Prototype)
原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。
原型模式主要涉及两个概念,浅拷贝与深拷贝。
浅拷贝:是指将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
深拷贝:是指将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。
说完理论,接着来举例:
首先先创建一个非基本类型的对象(为了能够实现深拷贝,此处创建的对象必须序列化):
/**
* @author chenglezheng
*/
public class Clone implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
接着我们创建一个浅拷贝对象
/**
* @author chenglezheng
*/
public class CloneShallow implements Cloneable{
private Clone clone;
private int test;
public int getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
public Clone getClone() {
return clone;
}
public void setClone(Clone clone) {
this.clone = clone;
}
public void print(){
System.out.println(clone);
System.out.println(clone.getName());
System.out.println(test);
}
@Override
protected CloneShallow clone() {
try{
return (CloneShallow) super.clone();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
再来创建一个深拷贝(深拷贝需要通过流的形式创建)
/**
* @author chenglezheng
*/
public class CloneDeep implements Serializable {
private Clone clone;
public Clone getClone() {
return clone;
}
public void setClone(Clone clone) {
this.clone = clone;
}
private int test;
public int getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
public void print(){
System.out.println(clone);
System.out.println(clone.getName());
System.out.println(test);
}
protected CloneDeep clone(CloneDeep clone) {
CloneDeep cloneDeep=null;
try{
/* 写入当前对象的二进制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(clone);
/* 读出二进制流产生的新对象 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
cloneDeep=(CloneDeep)ois.readObject();
return cloneDeep; //此处需要做流关闭,因为演示所以没弄
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
最后准备测试:
/**
* @author chenglezheng
*/
public class PrototypeTest {
public static void main(String[] args) {
Clone clone=new Clone();
clone.setName("张三");
System.out.println("浅拷贝测试结果...");
CloneShallow cloneShallow =new CloneShallow();
cloneShallow.setClone(clone);
cloneShallow.print();
CloneShallow cloneShallow1 = cloneShallow.clone();
cloneShallow1.print();
System.out.println("深拷贝测试结果...");
CloneDeep cloneDeep=new CloneDeep();
cloneDeep.setClone(clone);
cloneDeep.print();
CloneDeep cloneDeep1=cloneDeep.clone(cloneDeep);
cloneDeep1.print();
System.out.println("******************************");
System.out.println("浅拷贝测试结果1...");
clone.setName("李四");
cloneShallow.setClone(clone);
cloneShallow.setTest(10);
cloneShallow.print();
cloneShallow1.print();
System.out.println("深拷贝测试结果1...");
cloneDeep.setClone(clone);
cloneDeep.setTest(10);
cloneDeep.print();
cloneDeep1.print();
}
}
运行结果:
浅拷贝测试结果…
com.lc.clz.create.prototype.Clone@4554617c
张三
0
com.lc.clz.create.prototype.Clone@4554617c
张三
0
深拷贝测试结果…
com.lc.clz.create.prototype.Clone@4554617c
张三
0
com.lc.clz.create.prototype.Clone@378bf509
张三
0
浅拷贝测试结果1…
com.lc.clz.create.prototype.Clone@4554617c
李四
10
com.lc.clz.create.prototype.Clone@4554617c
李四
0
深拷贝测试结果1…
com.lc.clz.create.prototype.Clone@4554617c
李四
10
com.lc.clz.create.prototype.Clone@378bf509
张三
0
结果分析:
改变原对象中的name属性值,分别设置给浅复制对象和深复制对象
clone.setName(“李四”);
cloneShallow.setClone(clone);
cloneShallow.setTest(10);
cloneDeep.setClone(clone);
cloneDeep.setTest(10);
除此之外,不管浅复制还是深复制,基本的数据类型,int,long,float等都会完全复制,可以从以上的输出结果看出,所有复制对象的int输出都是0,而原对象输出的都是10;
总结:
原型模式的主要优点如下:
(1)当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率。
(2)原型模式提供了简化的创建模式,原型模式中产品的复制是通过封装在原型类中的克隆方法实现的,无须专门的创建。
(3)可以使用深克隆的方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用(如恢复到某一历史状态),可辅助实现撤销操作。
原型模式的主要缺点如下:
(1)需要为每一个类创建一个克隆方法,而克隆方法位于类的内部,当对已有的功能进行修改时,就需要修改源代码,这违背了设计模式的六大原则中的“开闭原则”。
(2)深复制的实现机制很复杂,且当对象之间存在多重的嵌套引用时,为了实现深复制,每一层对象对应的类都必须支持深复制,这样实现一个类似这样的对象复制就显的尤为复杂。
来源:CSDN
作者:LoungerM
链接:https://blog.csdn.net/LoungerM/article/details/103766019