設計模式(7)-原型模式詳解(易懂)

原型模式的定義

原型模式,用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。設計模式

Prototype原型模式是一種建立型設計模式,Prototype模式容許一個對象再建立另一個可定製的對象,根本無需知道任何如何建立的細節,工做原理是:經過將一個原型對象傳給那個要發動建立的對象,這個要發動建立的對象經過請求原型對象拷貝它們本身來實施建立。微信

模型:ide

image

經過模型發現,就是經過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()+"郵件發送成功了");
   }

運行:設計

image

考慮一個問題,須要發送郵件的數量不少的話,會很耗時。這時能夠用咱們今天的講的原型模式,來「克隆」出屬性一致的對象來實現。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()+"郵件發送成功了");
   }

運行:

image.gif

原型模式優勢

原型模式是在內存中二進制流的拷貝,要比直接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()+"");

我只打印的是原生對象的集合,可是運行的結果確實:

image

正好印證了我前面說的,這是淺拷貝。

若是想要深拷貝,在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
你們能夠關注個人微信公衆號:「安卓乾貨鋪」一個有質量、有態度的公衆號!

相關文章
相關標籤/搜索