什么是原型模式?
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。Java 中的 Object 类实现了 Cloneable,正是对这种设计模式的应用。
优缺点
优点:
1.性能提高。
2.逃避构造函数的约束。
缺点:
1.配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
2.必须实现 Cloneable 接口。
示例
作为一个坦克世界老玩家,提到原型,无法控制的想到虎式原型车。先创建一个 Tiger 类,一个 String 的车组编号,一个List 的车组成员信息。实现 Cloneable 接口并覆写 clone 接口。注意,如果不声明实现接口的话会报 CloneNotSupportedException 异常。
```
class Tiger implements Cloneable {
private String number;
private List<String> members;
public void setNumber(String number) {
this.number = number;
}
public String getNumber() {
return this.number;
}
public void setMembers(List<String> members) {
this.members = members;
}
public List<String> getMembers() {
return this.members;
}
@Override
public Tiger clone() {
try {
return (Tiger) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
我们再写一个测试类:
public static void main(String[] args) {
final Tiger tigerPrototype = new Tiger();
tigerPrototype.setNumber("001");
tigerPrototype.setMembers(List.of("Michael Wittmann", "Adelbert Schulz"));
final Tiger clonedTiger = tigerPrototype.clone();
System.out.println("tiger prototype number: " + tigerPrototype.getNumber());
System.out.println("Cloned tiger number: " + clonedTiger.getNumber());
System.out.println("Cloned object's reference addresses are same? " + (tigerPrototype == clonedTiger));
System.out.println("member's reference addresses are same? " + (tigerPrototype.getMembers() == clonedTiger.getMembers()));
}
Output:
tiger prototype number: 001
Cloned tiger number: 001
member's reference addresses are same? true
Cloned object's reference addresses are same? false
从输出结果我们可以看出,克隆出的对象和原型对象具有相同的属性值,但对象的内存地址是不同的,但其成员属性如果是引用数据类型,其引用是相同的,因此,如果原型对象中的 Member List 中有修改,其修改结果会反映到所有被克隆出的对象。这种克隆被称为“浅拷贝(Shallow Copy) ”,如果其所有成员属性也是值拷贝,享有独立的内存地址,即称为“深拷贝(Deep Copy) ”。深拷贝一般需要通过 I/O,序列化的途径。可以考虑使用 Apache Commons Lang 或 Gson 等工具来序列化。