原型模式
原型模式顾名思义就是以一个对象为基础复制出一个新的对象。
类图如下:
原型模式关键的类:
- Client 原型的调用者
- Prototype 声明复制方法的接口
- ConcretePrototype是具体的原型接口的实现
应用场景:
- 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。这是最常见的应用场景,而且在多线程调用中比较常见。
- 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
- 通过new产生一个对象需要非常繁琐的数据准备或访问权限,这时可以使用原型模式。
Java就已经支持原型模式了。我们需要继承Cloneable接口,复写clone方法实现自己的复制功能。
class ConcretePrototype implements Cloneable{
@NonNull
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
浅拷贝与深拷贝
默认情况下Java中的clone是浅拷贝,也就是说对于基本数据类型以及String数据类型进行的是值传递,而对于对象进行的是引用传递。我们来看看下面的例子。
public class Person implements Cloneable {
private PhoneNumber phoneNumber = new PhoneNumber();
private int age = 12;
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber.setNumber(phoneNumber);
}
public void setAge(int age) {
this.age = age;
}
@Override
protected Object clone() {
//浅copy,仅仅把phoneNumber的地址复制给了
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
@Override
public String toString() {
return "Person{" +
"phoneNumber=" + phoneNumber +
", age=" + age +
'}';
}
}
public class PhoneNumber {
private String number = "";
public void setNumber(String number) {
this.number = number;
}
public String getNumber() {
return number;
}
@Override
public String toString