原型模式定义如下:
用原型实例指定创建对象的种类,别且通过拷贝这些原型创建新的对象
原型模式的通用类图:
原型模式的有点:
1.性能优良
原型模式是在内存中二进制流的拷贝,比直接new一个对象性能好很多
2.逃避构造函数的约束
原型模式直接在内存中拷贝,不会执行构造函数
原型模式的使用场景
1.资源优化的场景
类初始化需要消耗很多资源
2.性能和安全要求的场景
通过new一个对象需要非常繁琐的数据准备和访问权限,则可以通过原型模式
3.一个对象对多个修改者的场景
原型模式在java中的体现就是克隆,即实现Cloneable ,覆盖clone()方法即可
克隆分文浅克隆和深克隆(或者叫浅拷贝和深拷贝)
浅拷贝的例子如下:
public class Thing implements Cloneable {
private List<String> list = new ArrayList<String>();
@Override
protected Thing clone() {
Thing thing = null;
try {
thing = (Thing) super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return thing;
}
public void setValue(String value) {
this.list.add(value);
}
public List<String> getValue() {
return this.list;
}
public static void main(String[] args) {
//生产一个对象
Thing thing=new Thing();
thing.setValue("小明");
//拷贝一个对象
Thing thing2=thing.clone();
thing2.setValue("小红");
System.out.println(thing.getValue());
}
}
大家觉得结果是什么?我们希望是:小明
但是结果是:[小明, 小红],结果说明,拷贝的结果并没有对象list进行拷贝,两个对象是共享一个list的,这就是浅拷贝
Object类提供的clone方法只拷贝本对象,对其内部的数组、引用等都不做拷贝,还是指向原生对象的内部元素地址
深拷贝代码如下:
public class Thing implements Cloneable {
private ArrayList<String> list = new ArrayList<String>();
@Override
protected Thing clone() {
Thing thing = null;
try {
thing = (Thing) super.clone();
this.list=(ArrayList<String>) this.list.clone();
} catch (Exception e) {
e.printStackTrace();
}
return thing;
}
public void setValue(String value) {
this.list.add(value);
}
public List<String> getValue() {
return this.list;
}
public static void main(String[] args) {
//生产一个对象
Thing thing=new Thing();
thing.setValue("小明");
//拷贝一个对象
Thing thing2=thing.clone();
thing2.setValue("小红");
System.out.println(thing.getValue());
}
}