一,什么是原型模式。
Prototype 模式 是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。
二,原型模式的特点。
由原型对象自身创建目标对象,通过实现接口 (Cloneable) ,目标对象是原型对象的一个克隆,不仅仅是具有相同的结构,属性,还与原型对象具有相同的值。
但是 在实例化目标对象,和实例化原型对象后, 在jvm 虚拟机 堆内存里是 两个地址不相同的引用对象。
根据对象克隆深度层次的不同,有浅度克隆与深度克隆。
三,实例。
3.1 浅度克隆
public class ProtoType implements Cloneable{
//浅度克隆基础数据类型
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public ProtoType cloneObject(){
try {
//每一个对象的父类的都是Object, object 实现了clone(), 这里可以直接调用
return (ProtoType)super.clone();
} catch (CloneNotSupportedException e) {
//没有实现(Cloneable)接口,会抛出不支持克隆异常,
e.printStackTrace();
return null;
}
}
@Override
public String toString() {
return "ProtoType{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", peopleList=" + peopleList +
'}';
}
}
public class Test {
public static void main(String[] args) {
//具有相同的值,和结构 ,浅度克隆
ProtoType protoType = new ProtoType();
protoType.setName("张三");
protoType.setAge("18");
System.out.println("原型对象===" +protoType.toString());
ProtoType protoType2 = protoType.cloneObject();
System.out.println("克隆对象===" +protoType.toString());
System.out.println("原型对象=克隆对象:"+(protoType == protoType2));
}
}
3.2 深度克隆对象
public class ProtoType implements Cloneable{
private String name;
private String age;
/**
* 深度克隆引用类型,使原型对象中的引用数据类型 与 模型对象中的引用数据类型 地址不一致
*/
private List<String> peopleList;
public List<String> getPeopleList() {
return peopleList;
}
public void setPeopleList(List<String> peopleList) {
this.peopleList = peopleList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public ProtoType cloneObject(){
try {
//每一个类的父类的都是Object, object 实现了clone(), 这里可以直接调用
ProtoType protoType =(ProtoType)super.clone();
//深度克隆原型对象中的引用数据类型,其实就是创建一个新的对象,
// 使原型对象中的引用数据类型 被克隆 模型对象时,让引用数据类型 地址不一致
List<String> list = new ArrayList<String>();
for(String str:this.peopleList){
list.add(str);
}
protoType.setPeopleList(list);
return protoType;
} catch (CloneNotSupportedException e) {
//没有实现(Cloneable)接口,会抛出不支持克隆异常,
e.printStackTrace();
return null;
}
}
@Override
public String toString() {
return "ProtoType{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", peopleList=" + peopleList +
'}';
}
}
public class Test {
public static void main(String[] args) {
//深度克隆
ProtoType protoType1 = new ProtoType();
List<String> peopleList = new ArrayList<String>();
peopleList.add("小王");
peopleList.add("小李");
protoType1.setPeopleList(peopleList);
ProtoType protoType2 = protoType1.cloneObject();
System.out.println(protoType1.getPeopleList());
System.out.println(protoType2.getPeopleList());
peopleList.add("小美");
protoType1.setPeopleList(peopleList);
System.out.println(protoType1.getPeopleList());
System.out.println(protoType2.getPeopleList());
}
}
总结:
在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据
希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全互补影响)
隐藏克隆操作的细节,很多时候,对对象本身的克隆需要涉及到本身的数据细节