概念
原型模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。是用于創(chuàng)建重復(fù)的對象,同時又能保證性能。指定創(chuàng)建對象的種類,通過拷貝復(fù)制這些原型,創(chuàng)建新的對象。當(dāng)直接創(chuàng)建對象的代價比較大時,則采用這種模式。
UML
拷貝方式
淺拷貝
@Data
@AllArgsConstructor
public class Parent {
private String name;
}
@Data
@AllArgsConstructor
public class Sleep1 implements Cloneable {
private String name;
private int age;
private String color;
//Parent 無需實(shí)現(xiàn)Cloneable 進(jìn)行拷貝
private Parent parent;
@Override
protected Sleep1 clone() {
Sleep1 sleep=null;
try {
sleep = (Sleep1) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println("clone失敗");
}
return sleep;
}
}
- 淺拷貝無法將屬性中為對象的類型加以拷貝,而是保存一份鏈接指向?qū)?yīng)對象
深拷貝
- 深拷貝則與淺拷貝相反,能將所有對象已經(jīng)屬性對象都拷貝一份
通過實(shí)現(xiàn)cloneable接口拷貝
- 缺點(diǎn)是所有引用的對象都需要實(shí)現(xiàn)拷貝,無限套娃,對類改動較大
@Data
@AllArgsConstructor
public class Child implements Cloneable {
private String name;
@Override
public Child clone() throws CloneNotSupportedException {
return (Child)super.clone();
}
}
@Data
@AllArgsConstructor
public class Sleep2 implements Cloneable {
private String name;
private int age;
private String color;
private Child child;
//深拷貝
@Override
protected Sleep2 clone() {
Sleep2 sleep=null;
try {
sleep = (Sleep2) super.clone();
sleep.child=child.clone();
} catch (CloneNotSupportedException e) {
System.out.println("clone失敗");
}
return sleep;
}
}
通過序列化來拷貝
@Data
@AllArgsConstructor
public class Sleep3 implements Serializable {
private String name;
private int age;
private String color;
private Parent parent;
public Sleep3 depepClone() {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try{
//序列化
bos=new ByteArrayOutputStream();
oos=new ObjectOutputStream(bos);
//將當(dāng)前對象以流方式輸出
oos.writeObject(this);
//反序列化
bis=new ByteArrayInputStream(bos.toByteArray());
ois=new ObjectInputStream(bis);
Sleep3 sleep3=(Sleep3) ois.readObject();
return sleep3;
}catch (Exception e){
System.out.println("反列化失敗");
return null;
}finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}