1. 概念
用原型的实例指定创建的种类并通过拷贝这些原型创建新的对象。
通俗:复制一模一样的对象出来。
目的:保护最原始的那一份存档,隐藏复制的过程。
2. 原理
在需要跟当前对象一模一样的对象时,直接使用该对象的克隆方法,避免手动去new对象,再逐一进行赋值等操作(这样就把复制过程隐藏)。同时,改变新的对象不会对原来的数据造成影响。
3. 代码示例
非重写clone()方法的方式,如果调用改方法,没有被重新,则会抛出异常。
3.1 定义一个对象的父接口
/**
* Created by rytong on 2017/10/10.
*/
public interface SuperIntrface {
}
3.2 定义一个克隆的接口
/**
* Created by rytong on 2017/10/10.
*/
public interface CloneInterface {
SuperIntrface cloneObject();
}
3.3 编写对象的实现
实现对象父接口、实现克隆接口,并封装克隆方法
/**
* Created by rytong on 2017/10/10.
*/
public class MyObject implements SuperIntrface ,CloneInterface{
private String filed1;
private int filed2;
private ArrayList<String> arrays;
public void setFiled1(String filed1) {
this.filed1 = filed1;
}
public void setFiled2(int filed2) {
this.filed2 = filed2;
}
public void setArrays(ArrayList<String> arrays) {
this.arrays = arrays;
}
public String getFiled1() {
return filed1;
}
public int getFiled2() {
return filed2;
}
public ArrayList<String> getArrays() {
return arrays;
}
@Override
public SuperIntrface cloneObject() {
MyObject myObject = new MyObject();
myObject.setFiled1(this.filed1);
myObject.setFiled2(this.filed2);
// 除8大基本类型和其封装类型外,只有String是深拷贝,所以list需要这样调用,才能深拷贝过去
myObject.setArrays((ArrayList<String>) this.arrays.clone());
return myObject;
}
}
3.4 克隆对象的使用
MyObject myObject = new MyObject();
myObject.setFiled1("这是字段1");
myObject.setFiled2(100);
ArrayList<String> strings = new ArrayList<>();
strings.add("123");
strings.add("345");
strings.add("567");
myObject.setArrays(strings);
// 使用克隆对象
MyObject cloneObject = (MyObject) myObject.cloneObject();
ArrayList<String> arrays = cloneObject.getArrays();
4. 深拷贝、浅拷贝
先引入一张图,图上的文字很好的说明了深拷贝和浅拷贝的区别。
- 深拷贝与浅拷贝问题中,会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。其余的都是浅拷贝。
- 直接复写Object的clone方法实现原型模式,可能会漏写导致抛出异常,需要注意。
- 原型模式一般很少单独使用,都是混合其他模式一起使用。