原型模式,用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。設計模式
Prototype原型模式是一種建立型設計模式,Prototype模式容許一個對象再建立另一個可定製的對象,根本無需知道任何如何建立的細節,工做原理是:經過將一個原型對象傳給那個要發動建立的對象,這個要發動建立的對象經過請求原型對象拷貝它們本身來實施建立。微信
模型:ide
經過模型發現,就是經過Clone()方法來實現對對象的拷貝。函數
好比某平臺舉行抽獎送福利的活動,中獎的通知以郵件形式發送。思考一下,這裏須要一個郵件Mail類用來填寫姓名,內容等信息。性能
下面實例說明,先寫普通Mail類和調用,而後再寫出原型模式的。學習
1.沒有實現Clone()方法的Mail類:this
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.調用spa
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()+"郵件發送成功了"); }
運行:設計
考慮一個問題,須要發送郵件的數量不少的話,會很耗時。這時能夠用咱們今天的講的原型模式,來「克隆」出屬性一致的對象來實現。code
下面修改了一個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; }
文章學習參考了《設計模式之禪》《大話設計模式》等等
另外能夠加入個人Android技術交流羣:458739310
你們能夠關注個人微信公衆號:「安卓乾貨鋪」一個有質量、有態度的公衆號!