一句話概述
原型模式是創建型模式的一種,其特點在于通過“復制”一個已經存在的實例來返回新的實例,而不是新建實例。被復制的實例就是我們所稱的“原型”,這個原型是可定制的。
原型模式多用于創建復雜的或者耗時的實例,因為這種情況下,復制一個已經存在的實例使程序運行更高效;或者創建值相等,只是命名不一樣的同類數據。
原型的實現
定義一個報紙模型
package com.example.xiao.prototype;
/**
* Created by xiao on 2017年4月24日,0024.
*/
import java.util.ArrayList;
import java.util.List;
/**
* 報紙
*/
public class Paper implements Cloneable{
private String text;//文字
private ArrayList<String> imgs;//圖片
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public List<String> getImgs() {
return imgs;
}
public void setImgs(ArrayList<String> imgs) {
this.imgs = imgs;
}
@Override
protected Paper clone() {
try {
Paper paper = (Paper) super.clone();
paper.text=this.text;
paper.imgs=this.imgs;
return paper;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
測試類
package com.example.xiao.prototype;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ArrayList<String> mImgs=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//構建paper1
Paper paper1=new Paper();
paper1.setText("paper1_text");
mImgs.add("paper1_img");
paper1.setImgs(mImgs);
//構建paper2
Paper paper2=paper1.clone();
paper2.setText("paper2_text");
paper2.getImgs().clear();
paper2.getImgs().add("paper2_img");
//打印測試
Log.d(TAG, "paper1 text: "+paper1.getText());
Log.d(TAG, "paper1 imgs: "+paper1.getImgs());
Log.d(TAG, "paper2 text: "+paper2.getText());
Log.d(TAG, "paper2 text: "+paper2.getImgs());
}
}
打印結果
Paste_Image.png
看到這,你可能有疑問,為什么paper1的圖片被改變了?
這是因為上面的克隆是淺拷貝,pager1和pager2的imgs屬性指向的是同一塊內存,pager2指向的對象改變了,pager1指向的對象當然會隨之改變。
避免這種情況的發生,推薦使用深拷貝。
深拷貝
imgs屬性也通過clone來賦值給新的對象
package com.example.xiao.prototype;
/**
* Created by xiao on 2017年4月24日,0024.
*/
import java.util.ArrayList;
import java.util.List;
/**
* 報紙
*/
public class Paper implements Cloneable{
private String text;//文字
private ArrayList<String> imgs;//圖片
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public List<String> getImgs() {
return imgs;
}
public void setImgs(ArrayList<String> imgs) {
this.imgs = imgs;
}
@Override
protected Paper clone() {
try {
Paper paper = (Paper) super.clone();
paper.text=this.text;
//paper.imgs=this.imgs;
//對imgs屬性也通過clone()方法,進行深拷貝
paper.imgs= (ArrayList<String>) this.imgs.clone();
return paper;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
打印結果
Paste_Image.png
以上就是克隆模式。