设计模式 - 学习笔记 - 原型模式Prototype Pattern
发布日期:2021-06-30 14:54:16
浏览次数:2
分类:技术文章
本文共 4326 字,大约阅读时间需要 14 分钟。
设计模式 - 学习笔记 - 原型模式Prototype Pattern
学习总结
- 对象创建模式。解耦:你别
new
你直接用interface
接就行了,要啥你直接叫我。 - 原型的特点就是自我复制。
Java
中的Cloneable
接口和它的clone()
方法想必都接触过吧。
动机 Motivation
- 在软件系统中,经常面临着“某些结构复杂的对象’的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
- 如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
应用场景
- 某个实例的创建过程非常耗费资源。但它又经常大量的用,那我们就是创建出一个作为原型,然后克隆…克隆…克隆…
- 比如关卡中的怪物、地图中的小兵。
UML
代码示例
1. 实现 Cloneable 接口: 浅拷贝
@Datapublic class Hero implements Cloneable { private String name; private int level ; private Listfriend; @Override protected Object clone() throws CloneNotSupportedException { return (Hero)super.clone(); }}
public class PrototypePatternDemo { public static void main(String[] args) throws CloneNotSupportedException { Hero hero = new Hero(); hero.setName("华安"); hero.setLevel(99); ArrayListheroes = new ArrayList<>(); heroes.add(new Hero()); heroes.add(new Hero()); hero.setFriend(heroes); Hero hero2 = (Hero)hero.clone(); hero2.setName("张三"); hero2.getFriend().get(0).setName("李四"); hero2.getFriend().get(1).setName("王五"); System.out.println(hero); System.out.println(hero2); }}
2. 实现自己定义接口 Prototype: 浅拷贝
public interface Prototype { Prototype clone();}
@Datapublic class Hero implements Prototype { private String name; private int level ; private Hero[] friend; @Override public Hero clone() { Hero hero = new Hero(); hero.setName(this.name); hero.setLevel(this.level); hero.setFriend(this.friend); return hero; }}
public class PrototypePatternDemo { public static void main(String[] args) throws CloneNotSupportedException { Hero hero = new Hero(); hero.setName("华安"); hero.setLevel(99); hero.setFriend(new Hero[]{ new Hero(), new Hero()}); Hero hero2 = (Hero)hero.clone(); hero2.setName("张三"); hero2.getFriend()[0].setName("李四"); hero2.getFriend()[1].setName("王五"); System.out.println(hero); System.out.println(hero2); }}
实现 Cloneable 接口,序列化/反序列化: 浅深贝
public interface Prototype { Prototype clone();}
@Datapublic class Hero implements Serializable, Prototype { private static final long serialVersionUID = 1L; private String name; private int level ; private Hero[] friend; @Override public Hero clone() { Hero hero = new Hero(); hero.setName(this.name); hero.setLevel(this.level); hero.setFriend(this.friend); return hero; } public Hero deepClone() { ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; ByteArrayInputStream bis = null; ObjectInputStream ois = null; try { // 序列化流 bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); // 输出当前对象 oos.writeObject(this); // 反序列化流 bis = new ByteArrayInputStream(bos.toByteArray()); ois = new ObjectInputStream(bis); return (Hero)ois.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { try { bos.close(); bis.close(); oos.close(); ois.close(); } catch (IOException e) { e.printStackTrace(); } } return null; }}
public class PrototypePatternDemo { public static void main(String[] args) throws CloneNotSupportedException { Hero hero = new Hero(); hero.setName("华安"); hero.setLevel(99); hero.setFriend(new Hero[]{ new Hero(), new Hero()}); Hero hero2 = (Hero)hero.clone(); hero2.setName("张三"); hero2.getFriend()[0].setName("李四"); hero2.getFriend()[1].setName("王五"); System.out.println(hero); System.out.println(hero2); System.out.println("---------------------------------------------"); Hero hero3 = (Hero)hero.deepClone(); hero3.setName("赵六"); hero3.getFriend()[0].setName("沈七"); hero3.getFriend()[1].setName("重八"); System.out.println(hero); System.out.println(hero3); }}
参考资料
转载地址:https://jerryjin.blog.csdn.net/article/details/115914222 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年05月06日 10时59分38秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
golang实现大数据量文件的排序
2019-04-30
golang中的time包
2019-04-30
2019NOIP D4题 加工领奖
2019-04-30
2021.5.19 JS高级第二天
2019-04-30
SpringBoot内置Tomcat配置参数
2019-04-30
ubuntu 快捷键
2019-04-30
linux 根目录下文件夹分析
2019-04-30
linux 查看分区和文件大小
2019-04-30
Not using PCAP_FRAMES 解释(snort中)
2019-04-30
技术转管理?这些“坑”你要绕道走
2019-04-30
领域驱动设计(DDD)前夜:面向对象思想
2019-04-30
Camera驱动调试小记
2019-04-30
四线触摸屏原理
2019-04-30
C/C++如何返回一个数组/指针
2019-04-30
腾讯AI语音识别API踩坑记录
2019-04-30
YbtOJ——递推算法【例题4】传球游戏
2019-04-30
安装openrave 0.9的各种依赖包
2019-05-01
kpm代码使用细节
2019-05-01
@FeignClient注解的重复名称解决
2019-05-01
java.net.BindException: 无法指定被请求的地址
2019-05-01