原型模式也是很簡(jiǎn)單的1種模式,對(duì)java來(lái)講已有相應(yīng)的接口了(Cloneable)。關(guān)于原型模式<<大話設(shè)計(jì)模式>>是以投放簡(jiǎn)歷作為例子講授的,即我要投放很多簡(jiǎn)歷,其實(shí)每一個(gè)簡(jiǎn)歷都1樣,所以只要我寫好1份,其他的復(fù)制就好了,其實(shí)就是今天講的原型模式,就是把要復(fù)制的類對(duì)象的屬性復(fù)制到另外1個(gè)對(duì)象上(其實(shí)不是復(fù)制而是對(duì)象的援用改變)。
原型模型:用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。
淺復(fù)制VS深復(fù)制
關(guān)于克隆有兩個(gè)概念
淺復(fù)制:就是只復(fù)制值類型的字段,不能復(fù)制援用的對(duì)象。意思就是簡(jiǎn)歷類中援用了其他的對(duì)象的話,這個(gè)援用對(duì)象的數(shù)據(jù)是不會(huì)復(fù)制的。
深復(fù)制:不進(jìn)復(fù)制值類型的字段,還復(fù)制援用的對(duì)象。區(qū)分淺復(fù)制不復(fù)制援用對(duì)象,深復(fù)制復(fù)制援用對(duì)象。
讓我們通過代碼來(lái)更好的理解它們吧
淺復(fù)制代碼
1、工作經(jīng)歷類(行將被簡(jiǎn)歷類所援用)
/*
* 工作經(jīng)歷
*/
publicclass WorkExperienceSimple {
private StringtimeArea;
public String getTimeArea() {
returntimeArea;
}
publicvoid setTimeArea(String timeArea) {
this.timeArea = timeArea;
}
}
2、簡(jiǎn)歷類(關(guān)鍵是實(shí)現(xiàn)了Cloneable接口)
/*
* 克隆中的淺復(fù)制代碼
*/
publicclass ResumeSimpleimplements Cloneable {
private Stringname;
//private String timeArea;
public WorkExperienceSimpletimeArea;
public ResumeSimple(String name){
this.name = name;
timeArea =new WorkExperienceSimple();
}
publicvoid setWorkExperience(String workName){
timeArea.setTimeArea(workName);
}
publicvoid display(){
System.out.println("簡(jiǎn)歷名稱:"+name);
System.out.println("工作地址:"+timeArea.getTimeArea());
}
@Override
public Object clone()throws CloneNotSupportedException {
ResumeSimpleo = null;
try {
o = (ResumeSimple) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
3、客戶端
publicclass PrototypeClient {
/**
* @param args
*/
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
//淺復(fù)制
System.out.println("--------淺復(fù)制開始----------");
ResumeSimpleresumeSimple =new ResumeSimple("大鳥");
resumeSimple.setWorkExperience("北京");
//克隆1,完善顯現(xiàn)
ResumeSimpleresumeSimple2;
try {
resumeSimple2= (ResumeSimple) resumeSimple.clone();
resumeSimple2.setWorkExperience("上海");
resumeSimple.display();
resumeSimple2.display();
}catch (CloneNotSupportedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
打印結(jié)果:
--------淺復(fù)制開始----------
簡(jiǎn)歷名稱:大鳥
工作地址:上海
簡(jiǎn)歷名稱:大鳥
工作地址:上海
看到了吧,工作經(jīng)歷都變成了上海,原來(lái)的北京沒有被復(fù)制過來(lái)。這就是工作經(jīng)歷類沒有被復(fù)制。
深復(fù)制
1、工作經(jīng)歷類(注意與淺復(fù)制區(qū)分)
/*
* 工作經(jīng)歷
* 與淺復(fù)制的區(qū)分1、實(shí)現(xiàn)了Cloneable接口2、實(shí)現(xiàn)接口的方法clone
*/
publicclassWorkExperienceDeepimplements Cloneable{
private StringtimeArea;
public String getTimeArea() {
returntimeArea;
}
publicvoid setTimeArea(String timeArea) {
this.timeArea = timeArea;
}
@Override
public Object clone()throws CloneNotSupportedException {
WorkExperienceDeep o =null;
try {
o = (WorkExperienceDeep)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
2、簡(jiǎn)歷類(注意區(qū)分的地方)
/*
* 克隆中的淺復(fù)制代碼
* 與淺復(fù)制區(qū)分1、改變工作經(jīng)歷類的初始化方式,即增加構(gòu)造函數(shù)ResumeDeep(WorkExperienceDeepworkName)
* 2、
*/
public class ResumeDeepimplements Cloneable {
private String name;
//private String timeArea;
public WorkExperienceDeep timeArea;
public ResumeDeep(String name){
this.name = name;
timeArea = new WorkExperienceDeep();
}
public ResumeDeep(WorkExperienceDeep workName){
try {
timeArea = (WorkExperienceDeep) workName.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setWorkExperience(String workName){
timeArea.setTimeArea(workName);
}
public void display(){
System.out.println("簡(jiǎn)歷名稱:"+name);
System.out.println("工作地址:"+timeArea.getTimeArea());
}
@Override
public Object clone(){
ResumeDeep o = new ResumeDeep(this.timeArea); //目的對(duì)工作經(jīng)歷進(jìn)行深復(fù)制
o.setName(name);
return o;
}
public void setName(String name) {
this.name = name;
}
}
3、客戶端
publicclass PrototypeClient {
/**
* @param args
*/
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
//淺復(fù)制
System.out.println("--------淺復(fù)制開始----------");
ResumeSimpleresumeSimple =new ResumeSimple("大鳥");
resumeSimple.setWorkExperience("北京");
//克隆1,完善顯現(xiàn)
ResumeSimpleresumeSimple2;
try {
resumeSimple2= (ResumeSimple) resumeSimple.clone();
resumeSimple2.setWorkExperience("上海");
resumeSimple.display();
resumeSimple2.display();
}catch (CloneNotSupportedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
//深復(fù)制
System.out.println("--------深復(fù)制開始----------");
ResumeDeepresumeDeep = new ResumeDeep("大鳥");
resumeDeep.setWorkExperience("北京");
//克隆1,完善顯現(xiàn)
ResumeDeepresumeDeep2;
resumeDeep2= (ResumeDeep) resumeDeep.clone();
resumeDeep2.setWorkExperience("上海");
resumeDeep.display();
resumeDeep2.display();
}
}
打印結(jié)果:
--------淺復(fù)制開始----------
簡(jiǎn)歷名稱:大鳥
工作地址:上海
簡(jiǎn)歷名稱:大鳥
工作地址:上海
--------深復(fù)制開始----------
簡(jiǎn)歷名稱:大鳥
工作地址:北京
簡(jiǎn)歷名稱:大鳥
工作地址:上海
很明顯深復(fù)制把工作經(jīng)歷類也復(fù)制了過來(lái),所以原來(lái)的北京值沒有變化。
附上原型模式結(jié)構(gòu)圖:
總結(jié):淺復(fù)制對(duì)值類型沒有問題,對(duì)援用類型,就只是復(fù)制了援用,對(duì)援用的對(duì)象還是只向了原來(lái)的對(duì)象,所以會(huì)出現(xiàn)兩個(gè)援用設(shè)置的“工作經(jīng)歷”,但是都是利用的最后的那個(gè)設(shè)置值,由于兩個(gè)援用指向了同1個(gè)對(duì)象。但我們可能需要這樣1種需求,把要復(fù)制的對(duì)象所援用的對(duì)象都復(fù)制1遍,那末我們就能夠選擇深復(fù)制的方式了。
附上代碼:http://download.csdn.net/detail/jzhf2012/8102153