原型模式,用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。設計模式
Prototype原型模式是一種建立型設計模式,Prototype模式容許一個對象再建立另一個可定製的對象,根本無需知道任何如何建立的細節,工做原理是:經過將一個原型對象傳給那個要發動建立的對象,這個要發動建立的對象經過請求原型對象拷貝它們本身來實施建立。ide
模型:函數
經過模型發現,就是經過Clone()方法來實現對對象的拷貝。性能
好比某平臺舉行抽獎送福利的活動,中獎的通知以郵件形式發送。思考一下,這裏須要一個郵件Mail類用來填寫姓名,內容等信息。學習
下面實例說明,先寫普通Mail類和調用,而後再寫出原型模式的。this
1.沒有實現Clone()方法的Mail類:spa
public class Mail {
//姓名
private String name;
//地址
private String address;
//內容
private String content;
public Mail(){
Log.e("qzs","構造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}設計
2.調用3d
private int MAIL_COUNT=10;
Mail mail=new Mail();
for (int i=0;i<MAIL_COUNT;i++){
mail.setName("姓名"+i);
mail.setAddress("www.xxx"+i+".com");
mail.setContent("xxxxx");
sendMail(mail);
}
public void sendMail (Mail mail){
Log.e("qzs",mail.getName()+"郵件發送成功了");
}orm
運行:
考慮一個問題,須要發送郵件的數量不少的話,會很耗時。這時能夠用咱們今天的講的原型模式,來「克隆」出屬性一致的對象來實現。
下面修改了一個Mail類:
public class Mail implements Cloneable{
//姓名
private String name;
//地址
private String address;
//內容
private String content;
public Mail(){
Log.e("qzs","構造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
protected Mail clone() throws CloneNotSupportedException {
Log.e("qzs","clone");
Mail mail=null;
try {
mail= (Mail) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return mail;
}
}
調用:
try {
Mail mail=new Mail();
Mail mail_clone=mail.clone();
for (int i=0;i<MAIL_COUNT;i++){
mail_clone.setName("姓名"+i);
mail_clone.setAddress("www.xxx"+i+".com");
mail_clone.setContent("xxxxx");
sendMail(mail_clone);
}
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
public void sendMail (Mail mail){
Log.e("qzs",mail.getName()+"郵件發送成功了");
}
運行:
原型模式是在內存中二進制流的拷貝,要比直接new一個對象性能好不少,尤爲是構造函數比較複雜,而且在循環體中生產出大量的對象時,用原型模式效率很高。
原型模式-在拷貝時構造函數是不執行的。(上面的例子中已經發現了)
淺拷貝:在經過Clone() 方法實現拷貝對象時,只是對對象的拷貝,而沒有對原生對象的其餘因素進行拷貝,因此拷貝出的對象還指向原生的。
深拷貝:這就好理解了,拷貝對象和原生對象是分開的。
下面經過一個例子來講明一下:
public class Text implements Cloneable{
private ArrayList<String> list=new ArrayList<>();
@Override
protected Text clone() throws CloneNotSupportedException {
Text text=null;
text= (Text) super.clone();
return text;
}
public void setList(String str){
this.list.add(str);
}
public ArrayList<String> getList(){
return this.list;
}
}
調用:
Text text=new Text();
Text text_clone=text.clone();
text.setList("1");
text_clone.setList("2");
Log.e("qzs",text.getList()+"");
我只打印的是原生對象的集合,可是運行的結果確實:
正好印證了我前面說的,這是淺拷貝。
若是想要深拷貝,在clone()方法中改一下就能夠了,其實就是對私有的變量list進行了拷貝:
@Override
protected Text clone() throws CloneNotSupportedException {
Text text=null;
text= (Text) super.clone();
//更改的
text.list= (ArrayList<String>) this.list.clone();
return text;
}
文章學習參考了《設計模式之禪》《大話設計模式》等等