原型設計模式
原型設計模式的定義是原型實例指定對象的類型,通過拷貝這些原型來創建新的對象
原型設計的例子
以<<大話設計模式>>例子為例子:我們求職投簡歷,經歷這一欄在投不同的公司需要修改,我們不要再去創建個人信息、工作經歷,
通過拷貝來減少簡歷中對象的創建。
簡歷父類
package com.learn.java.javabase.designpattern.prototype;
import lombok.Data;
@Data
public class Resume implements Cloneable {
private String id;
@Override
public Resume clone() throws CloneNotSupportedException {
Resume resume = null;
resume = (Resume) super.clone();
return resume;
}
}
簡歷的實現類
package com.learn.java.javabase.designpattern.prototype;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Data
@AllArgsConstructor
@Slf4j
public class CloneResume01 extends Resume {
private String name;
private String age;
private String year;
private String workInfo;
private Remark remark;
// public CloneResume01(Remark remark)
// {
// this.remark =remark.clone();
// }
public CloneResume01(String age, String name) {
this.age = age;
this.name = name;
}
public CloneResume01(String age, String name, Remark remark) {
this.age = age;
this.name = name;
this.remark = remark;
}
public void setWorkInfo(String year, String workinfo) {
this.year = year;
this.workInfo = workinfo;
}
public void display() {
log.info("name = {} ,age = {} , in year {} {},remark ={}", name, age, year, workInfo, remark.toString());
}
@Override
public CloneResume01 clone() {
CloneResume01 cloneResume01 =null;
try {
cloneResume01 = (CloneResume01) super.clone();
cloneResume01.setRemark(this.getRemark().clone());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return cloneResume01;
}
}
簡歷中的備注類Remark
備注類作為簡歷的一個屬性,因為淺復制只能復制String等基礎數據類型的值,但對於其他的引用類型並沒有拷貝值,只傳遞對象的引用地址
因此重寫Remark類的clone方法,進行深度復制,並在簡歷類中調用clone方法完成深度復制。
package com.learn.java.javabase.designpattern.prototype;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Remark implements Cloneable {
private String remarkValue;
@Override
public Remark clone() {
Remark remark = null;
try {
remark = (Remark) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return remark;
}
@Override
public String toString(){
return remarkValue;
}
}
測試類
package com.learn.java.javabase.designpattern.prototype;
public class TestProtoType {
public static void main(String[] args) {
CloneResume01 jackResume=new CloneResume01("fang","28","2017-2019","comp1"
,new Remark("first job"));
CloneResume01 jackResume02=jackResume.clone();
//Remark沒有實現clone方法,下面這句話會因為是復制新的Remark對象,所以打印的Remark是不一樣的
//jackResume02.setRemark(new Remark("second job"));
//淺復制和深復制,Remark和Resume實現類兩個clone方法沒有修改,會因為淺復制嗎,導致拷貝的實例的值與原型的值是一樣的
jackResume02.getRemark().setRemarkValue("second job");
jackResume02.setWorkInfo("2020-now","comp2");
jackResume.display();
jackResume02.display();
}
}
運行結果
22:44:53.007 [main] INFO com.learn.java.javabase.designpattern.prototype.CloneResume01 - name = fang ,age = 28 , in year 2017-2019 comp1,remark =first job
22:44:53.010 [main] INFO com.learn.java.javabase.designpattern.prototype.CloneResume01 - name = fang ,age = 28 , in year 2020-now comp2,remark =second job