原型模式

一句話概述

原型模式創建型模式的一種,其特點在于通過“復制”一個已經存在的實例來返回新的實例,而不是新建實例。被復制的實例就是我們所稱的“原型”,這個原型是可定制的。
原型模式多用于創建復雜的或者耗時的實例,因為這種情況下,復制一個已經存在的實例使程序運行更高效;或者創建值相等,只是命名不一樣的同類數據。

原型的實現

定義一個報紙模型

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

以上就是克隆模式。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容