原型模式

作者: zhangxiao | 来源:发表于2017-04-24 22:24 被阅读0次

    一句话概述

    原型模式创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。
    原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只是命名不一样的同类数据。

    原型的实现

    定义一个报纸模型

    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

    以上就是克隆模式。

    相关文章

      网友评论

        本文标题:原型模式

        本文链接:https://www.haomeiwen.com/subject/uyapzttx.html