原型模式
Posted pain-first
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原型模式相关的知识,希望对你有一定的参考价值。
--什么是原型模式?
--使用原型模式的应用场景?
--有哪几种原型模式?优缺点?
--原型模式的选择
定义
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
应用场景
- 对象之间相同或相似,即只是个别的几个属性不同的时候。
- 对象的创建过程比较麻烦,但复制比较简单的时候。
两种原型模式
1.浅克隆
创建一个新对象,新对象的属性和原来对象完全相同,对于引用类型属性,仍指向原有属性所指向的对象的内存地址。
注:(1)引用数据类型包括:类、接口类型、数组类型、枚举类型、注解类型,字符串型;
(2)基本数据类型,其包括包括数值型,字符型和布尔型。
为了更好的演示,先创建个引用类
Row.java
public class Row implements Cloneable {
private int n;
//省略getter,setter
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
浅克隆实现了Cloneable接口,并重写clone方法。
ShallowClone.java
public class ShallowClone implements Cloneable{
private String name;
private Date birthday;
private Row row;
public ShallowClone() {
}
public ShallowClone(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
//省略getter,setter
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Row row = new Row();
ShallowClone person1 = new ShallowClone("lihui", new Date());
person1.setRow(row);
ShallowClone person2 = (ShallowClone) person1.clone();
row.setN(1);
System.out.println(person1 == person2); // false
System.out.println(person1.row == person2.row); // true
}
}
debug看各个属性的引用地址,仔细观察不难发现,克隆的对象除了person2对象的内存地址地址和person1的不一致,其余的引用类型属性都指向相同的地址。 也就是说,当执行row.setN(1)的时候,不但会修改person1的row的值,也会修改person2的row的值。
2.深克隆
创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
深克隆不但实现了Cloneable接口和重写clone方法,该类的引用类型属性也实现了Cloneable接口和重写clone方法,并且在该类的clone方法中调用clone方法进行了赋值。
DeepClone.java
public class DeepClone implements Cloneable{
private String name;
private Date birthday;
private int num;
private Row row;
public DeepClone() {
}
public DeepClone(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
//省略getter,setter
@Override
protected Object clone() throws CloneNotSupportedException {
DeepClone person = (DeepClone) super.clone();
// 这里对对象内的引用类型属性进行克隆,使克隆更深入
person.row = (Row) person.row.clone();
return person;
}
public static void main(String[] args) throws CloneNotSupportedException {
Row row = new Row();
DeepClone person1 = new DeepClone("lihui", new Date(0L));
person1.setRow(row);
DeepClone person2 = (DeepClone) person1.clone();
row.setN(1);
System.out.println(person1 == person2); // false
System.out.println(person1.row == person2.row); // false
}
}
debug看各个属性的引用地址,发现person2和person1的对象和所有引用类型的属性的地址都不一样。所以引用对象修改值的时候,只会影响到原本的引用地址里面的值,而不会影响到克隆对象属性的值。
也就是说,当执行row.setN(1)的时候,只会修改person1的row的值,不会修改person2的row的值。
区别
深浅克隆都会在堆中新分配一块区域,区别在于对象属性引用的对象是否需要进行克隆(递归性的)。
参考:
什么叫引用? https://blog.csdn.net/qq_44231628/article/details/86064762
浅克隆和深克隆 https://www.cnblogs.com/1314xf/p/10139971.html ????????????????????????https://www.jianshu.com/p/8caf745d8ca6
以上是关于原型模式的主要内容,如果未能解决你的问题,请参考以下文章