Android开发Android知识

原型模式

2017-04-24  本文已影响0人  zhangxiao

一句话概述

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

原型的实现

定义一个报纸模型

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

以上就是克隆模式。

上一篇下一篇

猜你喜欢

热点阅读