原型模式(Prototype):
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
我们言简意赅的看如下几个代表其特性的关键语,duang的一下就懂了的。
- 创建型设计模式。
- 适用复杂的创建过程对象。
- 克隆实例。
- 不执行构造函数
- 速度快,安全,省资源。
看完上面就有个大概,然后我们再提出一个概念:
原型:要被克隆的实例。
浅拷贝:对原型的基本数据类型复制,对象类型只复制其引用,不复制对象。即克隆出来的实例仍用原型里引用类型的对象实体。
深拷贝:全部复制。
Code
直接上代码:
class Prototype implements Cloneable {
public String memory;
public ArrayList<String> list = new ArrayList<String>();
public void AddData(String s){
list.add(s);
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
protected Object clone() {
Prototype prototype2=null;
try {
prototype2=(Prototype) super.clone();
//解开注释即为深拷贝
// prototype2.list=(ArrayList<String>) this.list.clone();
} catch (CloneNotSupportedException e) {
}
return prototype2;
}
}
public class Main1 {
public static void main(String[] args) {
Prototype prototype = new Prototype();
prototype.setMemory("2G");
prototype.AddData("a");
Prototype prototype2 = (Prototype) prototype.clone();
prototype2.setMemory("4G");
prototype2.AddData("b");
System.out.println(prototype.toString() +" 内存:" + prototype.getMemory() + " list hashCode:" + prototype.list.hashCode());
System.out.println(prototype2.toString() +" 内存:" + prototype2.getMemory() + " list hashCode:" + prototype2.list.hashCode());
System.out.println("打印 prototype.list 里面的元素");
for (String string : prototype.list) {
System.out.print(string+" ");
}
System.out.println();
System.out.println("打印 prototype2.list 里面的元素");
for (String string : prototype2.list) {
System.out.print(string+" ");
}
}
}
运行结果
根据前文的说明,我们知道,clone原型的时候如果没有对引用类型的变量就行独立拷贝,那么拷贝出来的对象的引用类型将和原型公用一个堆,也就是指向相同的地址,参考运行结果里面hashCode都是4066和里面的元素都是a,b 。
我们解开注释,查看运行结果。
如上图所示,两list已不是同一ArrayList对象。
-----------------------------------------------------------我是分割线----------------------------------------------------------------
原型模式使用场景:
● 资源优化场景
类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
● 性能和安全要求的场景
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
● 一个对象多个修改者的场景
一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
注意:
final 变量不可以被clone。