首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

“补课”进行时:设计模式(6)——原型模式

1. 前文汇总

2. 找工作

这一天,郭靖大侠因为在桃花岛调戏侍女被黄蓉打出了桃花岛,这下可玩大了,从桃花岛被赶出来吃啥喝啥啊,得赶紧找份工作,西北风可喝不饱肚子哇~~~

这不,我们的郭大侠就开始写简历,准备向丐帮、全真教、白驼山和段氏家族投一份简历,看看能不能先混碗饭吃,等老婆的气消了再回去。

首先,先定义一个简历类:

然后,我们的郭大侠开始了熬夜写简历的生活:

简历这么一份一份的写太累了,工作都没找到可能先饿死了,不行,小郭同学需要提高写简历的效率,于是,他去找了一个打印机回来:

这个时候,感觉效率好像还是有点低,每次只能一张一张打印,浪费时间,于是乎,我们的郭大侠又去搞了一个复印机回来。

可是使用复印机需要我们原本的简历支持这个功能,听过这个功能需要扩展 Cloneable 接口:

然后我们的复印机就能跑起来了:

这里实际上我们只有第一个对象是使用打印机打印出来的,后面的对象都是通过复印机直接复印出来的。

这其实就是设计模式中的原型模式。

3. 原型模式

原型模式(Prototype Pattern)的简单程度仅次于单例模式和迭代器模式。正是由于简单,使用的场景才非常地多,其定义如下:

Specify the kinds of objects to create using a prototypical instance,andcreate new objects by copying this prototype.(用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。)

这个绝对是最简单的设计模式,整个模式的核心就只有一个 clone 方法,通过该方法进行对象的拷贝, Java 提供了一个 Cloneable 接口来标示这个对象是可拷贝的,为什么说是「标示」呢?翻开 JDK 的帮助看看 Cloneable 是一个方法都没有的,这个接口只是一个标记作用,在 JVM 中具有这个标记的对象才有可能被拷贝。那怎么才能从「有可能被拷贝」转换为「可以被拷贝」呢?方法是覆盖 方法。

通用代码:

优点:

性能优良

原型模式是在内存二进制流的拷贝,要比直接 new 一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。

逃避构造函数的约束

这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的。优点就是减少了约束,缺点也是减少了约束。

4. 构造函数

先看一个简单的有关构造函数的示例:

执行结果如下:

就输出一次,这里可以证明对象拷贝的时候构造函数是不会执行的,原因在于拷贝是直接在堆中进行,这其实也可以理解, new 的时候, JVM 要走一趟类加载流程,这个流程非常麻烦,在类加载流程中会调用构造函数,最后生成的对象会放到堆中,而拷贝就是直接拷贝堆中的现成的二进制对象,然后重新一个分配内存块。

5. 浅拷贝和深拷贝

先看一个浅拷贝的案例:

执行的结果是:

这种情况就是浅拷贝, Java 只拷贝你指定的对象,至于你指定的对象里面的别的对象,它不拷贝,还是把引用给你,共享变量,这是一种非常不安全的方式,需要特别注意。

内部的数组和引用对象不会拷贝,其他的原始基本类型和 String 类型会被拷贝。

那么这种情况如何进行一个深拷贝呢?只需要修改一下刚才 clone 的方法:

还是刚才的测试类,这次的运行结果是:

感谢阅读

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20201102A0290900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券