定義:通過拷貝一個已經存在的實例來返回新的實例,而不是新建實例。被拷貝的實例就稱爲原型。
類圖
原型類實現思路
(1)實現Cloneable接口。(在Java虛擬機中,只有實現了這個接口的類纔可以被拷貝。)
(2)重寫Object類中的clone方法。(作用是返回對象的一個拷貝,但其作用域是protected,要修改成public。)
原型模式中的拷貝分爲“淺拷貝”和“深拷貝”。
淺拷貝
對值類型的成員變量進行值的複製,對引用類型的成員變量只複製引用、不復制引用的對象。
深拷貝
對值類型的成員變量進行值的複製,對引用類型的成員變量也進行引用對象的複製。
Object類的clone方法只會拷貝對象中的基本的數據類型,對於String類型、數組、容器對象、引用對象等都不會拷貝。如果要實現深拷貝,必須對String類型、數組、容器對象、引用對象等另行拷貝。Java提供的大部分容器類都實現了Cloneable接口。
例子
原型類
public class Prototype implements Cloneable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
}
public class LightPrototype extends Prototype{
public void display(){
System.out.println(this.getName());
}
}
測試類
public class LightPrototypeTest {
public static void main(String[] args){
LightPrototype lightPrototype = new LightPrototype();
lightPrototype.setName("original lightPrototype!");
LightPrototype copyLightPrototypePrototype = (LightPrototype)lightPrototype.clone();
System.out.println(copyLightPrototypePrototype.getName());
}
}
public class DeepPrototype implements Cloneable{
private String id;
private Prototype prototype;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Prototype getPrototype() {
return prototype;
}
public void setPrototype(Prototype prototype) {
this.prototype = prototype;
}
@Override
public DeepPrototype clone(){
DeepPrototype deepPrototype = null;
try{
deepPrototype = (DeepPrototype)super.clone();
//對引用對象的拷貝
deepPrototype.prototype = (Prototype)this.prototype.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return deepPrototype;
}
}
測試類
public class DeepPrototypeTest {
public static void main(String[] args){
Prototype prototype = new Prototype();
prototype.setName("original Prototype!");
DeepPrototype deepPrototype = new DeepPrototype();
deepPrototype.setId("deepPrototype id!");
deepPrototype.setPrototype(prototype);
DeepPrototype copyDeepPrototypePrototype = (DeepPrototype)deepPrototype.clone();
System.out.println(copyDeepPrototypePrototype.getId());
System.out.println(copyDeepPrototypePrototype.getPrototype().getName());
}
}