原型模式

原型模式

定义:Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
原型模式的优点及适用场景
  • 使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
  • 使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
  • 因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。
类图:

这里写图片描述

具体代码:

Cloneable接口相当于类图中的Prototype类,People是具体的实现了类

public class People implements Cloneable {

    private String name;
    private int age;
    private ArrayList<Finger> list = new ArrayList<>();

    public People clone() {
        try {
            People p = (People) super.clone();

            ArrayList<Finger> list1 = new ArrayList<>();

            for (Finger f : list) {
                Finger f1 = f.clone();
                list1.add(f1);
            }

            p.setList(list1);

            return p;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public ArrayList<Finger> getList() {
        return list;
    }

    public void setList(ArrayList<Finger> list) {
        this.list = list;
    }
}

为了实现浅拷贝和深拷贝的区别,所以特意加了一个Finger类,实现Cloneable接口

public class Finger implements Cloneable {

    public Finger clone() {
        try {
            return (Finger) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return null;
    }
}

测试类

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
    }

    private void init() {
        People people2 = new People();
        people2.setName("张三");
        people2.setAge(18);
        ArrayList<Finger> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            list.add(new Finger());
        }
        people2.setList(list);

        Log.e("zhang", "people2:" + people2.toString() + " name:" + people2.getName() + "===age:" + people2.getAge());

        for (Finger f2 : people2.getList()) {
            Log.e("zhang", "people2: f:" + f2.toString());
        }

        People people3 = people2.clone();
        Log.e("zhang", "people3:" + people3.toString() + " name:" + people3.getName() + "===age:" + people3.getAge());

        for (Finger f3 : people3.getList()) {
            Log.e("zhang", "people3: f:" + f3.toString());
        }
    }
}

打印的结果:

people2:www.weshared.yuanxingmode.People@1b198fdb name:张三===age:18
 f:www.weshared.yuanxingmode.Finger@32192a78
 f:www.weshared.yuanxingmode.Finger@1077d551
 f:www.weshared.yuanxingmode.Finger@13aab1b6

 people3:www.weshared.yuanxingmode.People@a974eb7 name:张三===age:18
 f:www.weshared.yuanxingmode.Finger@34f27624
 f:www.weshared.yuanxingmode.Finger@2f13758d
 f:www.weshared.yuanxingmode.Finger@31283342

可以看出通过clone()方法拷贝出来的的是一个新的对象(内存地址值不同)


浅拷贝与深拷贝
浅拷贝实现方式:通过clone()方法克隆对象,但未对所持有的类的引用使用clone()方法,会导致类的引用有所持有的内存地址值是相同的。
 public Finger clone() {
        try {
            return (Finger) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return null;
    }
深拷贝:clone出来的是一个独立的,完全拥有自己的内存地址值。
public People clone() {
        try {
            People p = (People) super.clone();

            ArrayList<Finger> list1 = new ArrayList<>();

            for (Finger f : list) {
                Finger f1 = f.clone();
                list1.add(f1);
            }

            p.setList(list1);

            return p;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
一般尽量用深拷贝。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值