【GOF23设计模式】原型模式

【GOF23设计模式】原型模式

来源:http://www.bjsxt.com/ 
一、【GOF23设计模式】_原型模式、prototype、浅复制、深复制、Cloneable接口 
原型模式

浅复制

 1 package com.test.prototype;
 2 
 3 import java.util.Date;
 4 
 5 /**
 6  * 浅复制
 7  */
 8 public class Sheep implements Cloneable{//Cloneable为标记接口
 9     private String sname;
10     private Date birthday;
11 
12     @Override
13     protected Object clone() throws CloneNotSupportedException {
14         Object obj = super.clone();//直接调用object对象的clone()方法
15         return obj;
16     }
17 
18     public Sheep() {
19     }
20 
21     public Sheep(String sname, Date birthday) {
22         super();
23         this.sname = sname;
24         this.birthday = birthday;
25     }
26 
27     public String getSname() {
28         return sname;
29     }
30 
31     public void setSname(String sname) {
32         this.sname = sname;
33     }
34 
35     public Date getBirthday() {
36         return birthday;
37     }
38 
39     public void setBirthday(Date birthday) {
40         this.birthday = birthday;
41     }
42 }
 1 package com.test.prototype;
 2 
 3 import java.util.Date;
 4 /**
 5  * 测试原型模式(浅复制)
 6  */
 7 public class Client {
 8     public static void main(String[] args) throws Exception {
 9         Date date = new Date(3333332323L);
10         Sheep s1 = new Sheep("少利", date);
11         Sheep s2 = (Sheep) s1.clone();
12 
13         System.out.println(s1);
14         System.out.println(s1.getSname());
15         System.out.println(s1.getBirthday());
16         date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改
17         System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday()
18 
19         s2.setSname("多利");
20         System.out.println(s2);
21         System.out.println(s2.getSname());
22         System.out.println(s2.getBirthday());
23     }
24 }

控制台输出:s1修改时间后,s2的也跟着改(Fri Dec 10 00:59:15 CST 12500)

com.test.prototype.Sheep@1db9742
少利
Sun Feb 08 21:55:32 CST 1970
Fri Dec 10 00:59:15 CST 12500
com.test.prototype.Sheep@647e05
多利
Fri Dec 10 00:59:15 CST 12500

深复制

 1 package com.test.prototype;
 2 
 3 import java.util.Date;
 4 
 5 /**
 6  * 深复制
 7  */
 8 public class Sheep2 implements Cloneable{//Cloneable为标记接口
 9     private String sname;
10     private Date birthday;
11 
12     @Override
13     protected Object clone() throws CloneNotSupportedException {
14         Object obj = super.clone();//直接调用object对象的clone()方法
15 
16         //添加如下代码实现深复制(Deep Clone)
17         Sheep2 s = (Sheep2) obj;
18         s.birthday = (Date) this.birthday.clone();//属性克隆!
19 
20         return obj;
21     }
22 
23     public Sheep2() {
24     }
25 
26     public Sheep2(String sname, Date birthday) {
27         super();
28         this.sname = sname;
29         this.birthday = birthday;
30     }
31 
32     public String getSname() {
33         return sname;
34     }
35 
36     public void setSname(String sname) {
37         this.sname = sname;
38     }
39 
40     public Date getBirthday() {
41         return birthday;
42     }
43 
44     public void setBirthday(Date birthday) {
45         this.birthday = birthday;
46     }
47 }
 1 package com.test.prototype;
 2 
 3 import java.util.Date;
 4 /**
 5  * 测试原型模式(深复制)
 6  */
 7 public class Client2 {
 8     public static void main(String[] args) throws Exception {
 9         Date date = new Date(3333332323L);
10         Sheep2 s1 = new Sheep2("少利", date);
11         Sheep2 s2 = (Sheep2) s1.clone();
12 
13         System.out.println(s1);
14         System.out.println(s1.getSname());
15         System.out.println(s1.getBirthday());
16         date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改
17         System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday()
18 
19         s2.setSname("多利");
20         System.out.println(s2);
21         System.out.println(s2.getSname());
22         System.out.println(s2.getBirthday());
23     }
24 }

控制台输出:s1修改时间后,s2还是最初的(Sun Feb 08 21:55:32 CST 1970)

com.test.prototype.Sheep2@1db9742
少利
Sun Feb 08 21:55:32 CST 1970
Fri Dec 10 00:59:15 CST 12500
com.test.prototype.Sheep2@647e05
多利
Sun Feb 08 21:55:32 CST 1970

二、【GOF23设计模式】_原型模式、反序列化实现深复制、效率对比、创建型模式总结 
利用序列化和反序列化技术实现深复制

 1 package com.test.prototype;
 2 
 3 import java.io.ByteArrayInputStream;
 4 import java.io.ByteArrayOutputStream;
 5 import java.io.ObjectInputStream;
 6 import java.io.ObjectOutputStream;
 7 import java.util.Date;
 8 /**
 9  * 原型模式(使用序列化和反序列化的方式实现深复制)
10  */
11 public class Client3 {
12     public static void main(String[] args) throws Exception {
13         Date date = new Date(3333332323L);
14         Sheep s1 = new Sheep("少利", date);
15 
16         System.out.println(s1);
17         System.out.println(s1.getSname());
18         System.out.println(s1.getBirthday());
19 
20 //      Sheep s2 = (Sheep) s1.clone();
21         //使用序列化和反序列化实现深复制
22         //序列化
23         ByteArrayOutputStream bos = new ByteArrayOutputStream();
24         ObjectOutputStream    oos = new ObjectOutputStream(bos);
25         oos.writeObject(s1);
26         byte[] bytes = bos.toByteArray();
27 
28         //反序列化
29         ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
30         ObjectInputStream    ois = new ObjectInputStream(bis);
31 
32         Sheep s2 = (Sheep) ois.readObject();//深复制的对象
33 
34         System.out.println("修改原型对象的属性值");
35         date.setTime(332324355555555L);
36         System.out.println(s1.getBirthday());
37 
38         s2.setSname("多利");
39         System.out.println(s2);
40         System.out.println(s2.getSname());
41         System.out.println(s2.getBirthday());
42     }
43 }

短时间大量创建对象时,原型模式和普通new方式效率测试:

 1 package com.test.prototype;
 2 /**
 3  * 测试普通new方式创建对象和clone方式创建对象的效率差异!
 4  * 如果需要短时间创建大量对象,并且new的过程比较耗时,则可以考虑使用原型模式!
 5  */
 6 public class Client4 {
 7 
 8     public static void testNew(int size){
 9         long start = System.currentTimeMillis();
10         for (int i = 0; i < size; i++) {
11             Laptop t = new Laptop();
12         }
13         long end = System.currentTimeMillis();
14         System.out.println("new的方式创建耗时:" + (end - start));
15     }
16 
17     public static void testClone(int size) throws CloneNotSupportedException{
18         long start = System.currentTimeMillis();
19         Laptop t = new Laptop();
20         for (int i = 0; i < size; i++) {
21             Laptop temp = (Laptop) t.clone();
22         }
23         long end = System.currentTimeMillis();
24         System.out.println("clone的方式创建耗时:" + (end - start));
25     }
26 
27     public static void main(String[] args) throws Exception {
28         testNew(1000);
29         testClone(1000);
30     }
31 }
32 
33 class Laptop implements Cloneable{//笔记本电脑
34     public Laptop(){
35         try{
36             Thread.sleep(10);//模拟创建对象耗时的过程!
37         }catch(InterruptedException e){
38             e.printStackTrace();
39         }
40     }
41 
42     @Override
43     protected Object clone() throws CloneNotSupportedException {
44         Object obj = super.clone();//直接调用object对象的clone()方法
45         return obj;
46     }
47 }

控制台输出:

new的方式创建耗时:10168
clone的方式创建耗时:10

开发中的应用场景: 
原型模式很少单独出现,一般和工厂模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。 
spring中bean的创建实际就是两种:单例模式和原型模式(原型模式需要和工厂模式搭配起来)。

创建型模式的总结: 
创建型模式的总结

posted on 2016-08-24 12:30 ErBing 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/erbing/p/5802444.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/256518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Deepfacelab 小白教程

不小心入了AI换脸的坑&#xff0c;但是感觉AI换脸很有意思&#xff0c;第一次感觉科研使我快乐。 目录 一、AI换脸软件简介 二、Deepfacelab下载安装 三、Deepfacelab Demo实现 四、Deepfacelab 填坑 五、总结 一、AI换脸软件简介 这个没有具体使用过&#xff0c;目前我…

Underscore.js 的模板功能

Underscore是一个非常实用的JavaScript库&#xff0c;提供许多编程时需要的功能的支持&#xff0c;他在不扩展任何JavaScript的原生对象的情况下提供很多实用的功能。 无论你写一段小的js代码&#xff0c;还是写一个大型的HTML5应用&#xff0c;underscore都能帮上忙。目前&…

ANSYS——查看剖面图的应力分布云图以及工作平面的相关设置

剖面图和切片图其实差不多,只是切片图只有一个截面,而剖面图是切去一部分保留另一部分模型,不但可以看到截面处应力分布还可以看到剩余模型的应力分布 切片应力云图可见:https://blog.csdn.net/qq_45769063/article/details/106357700 1.剖面云图的查看 首先将工作平面的…

2016.8.2

高端内存映射方式 高端内存映射分为三种&#xff1a;永久映射、临时映射和非连续动态内存映射。高端内存一般是指896MB以上的页框&#xff0c;这段区间内核一般不能直接访问。 1.永久映射 永久内核映射允许内核建立高端页框到内核地址空间的长期映射。它们使用主内核页表中的一…

深度学习之pytorch(三) C++调用

玩深度学习&#xff0c;个人觉得基于anaconda的python适合开发与测试&#xff0c;C适合实际的工程部署&#xff01;而pytorch官方有编译好的libtorch&#xff0c;特别方便&#xff0c;适合于我这样的伸手党和手残党(win10下编译tensorflow编译了好久都没通过&#xff0c;好忧伤…

机器学习(一) 基于sklearn库的数据集划分(交叉验证)

机器学习中首要环节就是数据集的处理&#xff0c;其中数据集的处理从个人理解(如有错误敬请谅解)的角度来说包括两个方面&#xff1a;数据集划分和数据清理。其中数据集划分是指训练集、验证集和测试集的数据类别划分&#xff1b;数据清理是指数据的清洗、删除等等方面。这两天…

敏捷项目开源管理软件ScrumBasic(2)- 多项目支持

1.加入Project对象模型 public class Project{[Key][MaxLength(32)]public string ID { get; set; }public string Name { get; set; }public int Order { get; set; }public ICollection<UserStory> Stories { get; set; }public ApplicationUser Creator { get; set; }…

postgresql表和列注释(描述)

2019独角兽企业重金招聘Python工程师标准>>> PostgreSQL添加表和列注释。本文为测试表test&#xff0c;默认无注释。 test# \d关联列表架构模式 | 名称 | 类型 | 拥有者 | 大小 | 描述 -------------------------------------------------public | test | …

Fifth scrum meeting - 2015/10/30

概述 从昨天开始&#xff0c;我们的开发工作终于进入了正轨&#xff0c;由于之前没有mooc服务器API接口&#xff0c;一些工作无法进行。 因为我们团队开始开发较晚&#xff0c;因此我们将开发阶段的截至时间定为了下周五&#xff0c;测试阶段则压缩为下周周六和周日两天。 我们…

计算机加入域 不能访问网络位置 解决办法

计算机加入域 不能访问网络位置 解决办法 启动以下服务 本文转自 onesthan 51CTO博客&#xff0c;原文链接&#xff1a;http://blog.51cto.com/91xueit/1660286&#xff0c;如需转载请自行联系原作者

Android Camera HAL浅析

1、Camera成像原理介绍 Camera工作流程图 Camera的成像原理可以简单概括如下&#xff1a; 景物(SCENE)通过镜头&#xff08;LENS&#xff09;生成的光学图像投射到图像传感器(Sensor)表面上&#xff0c;然后转为电信号&#xff0c;经过A/D&#xff08;模数转换&#xff09;转换…

win10 下pycharm+anaconda 编译生成pyd文件

由于生产部署的问题&#xff0c;需要把用python写的深度学习代码编译为可被调用的文件。上网搜索了下&#xff0c;暂时了解到win10下pyd文件比较流行。下面是直接引用某位博主的结论&#xff0c;个人感觉总结的很好。其中Cython库将已有的Python代码转化为C语言的代码&#xff…

JVM(4)之 使用MAT排查堆溢出

为什么80%的码农都做不了架构师&#xff1f;>>> 接下来讲解如何设置以及当发生堆溢出的时候怎么排查问题。先看一小段代码&#xff1a;   代码中使用了一个无限循环来为list添加对象&#xff0c;如果采用默认的堆大小的话可能要等待好久才能出现堆溢出的错误&a…

caffe 中的一些参数介绍

转自&#xff1a;http://blog.csdn.net/cyh_24/article/details/51537709 solver.prototxt net: "models/bvlc_alexnet/train_val.prototxt" test_iter: 1000 # test_interval: 1000 # base_lr: 0.01 # 开始的学习率 lr_policy: "step" # 学习率的…

python 制作二进制文件数据集(bin)

为了方便进行深度学习的程序调用与实现&#xff0c;需要将excel的数据文件转换为二进制文件。好处就是接口统一&#xff0c;读写速度快&#xff0c;节约空间。 一、调用库 使用xlrd读入execel表格&#xff0c;经过处理后转换为对应的dataframe结构&#xff0c;再使用pickle库…

远程连接mysql数据库注意点记录

一、如何新建独立帐号并设置权限 这里我使用Navicat作为我的数据库管理工具&#xff0c;打开Navicat。 选择“用户”--“新建用户” 输入用户名、主机、密码&#xff0c;需要注意的是&#xff0c;主机那不是写“localhost”&#xff0c;而是写“%” 然后可以设置“服务器权限”…

【域控管理】父域的搭建

从这篇博文开始&#xff0c;所有的域控系统都是在虚拟机中创建的。 在VM里安装Windows Server 2008 R2的方法就不多说了&#xff0c;无脑式安装&#xff0c;略过不提。 进到系统桌面&#xff0c;打开本地连接&#xff0c;设置网卡的IP地址&#xff0c;如下图&#xff1a; 注意&…

tensorflow2 tensorboard可视化使用

tensorflow2自带tensorboard&#xff0c;所以不必再自行安装tensorboard。 一、使用环境 win10 x64&#xff1b; anaconda3tensorflow2&#xff08;cpu版本&#xff09; 二、使用 1.在模型训练之前插入以下代码 log_dir os.path.join(logs) #win10下的bug&#xff0c; if…

IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)...

首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context是图形上下文,可以将其理解为一块画布,我们可以在上面进行绘画操作,绘制完成后,将画布放到我们的view中显示即可,view看作是一个画框. 自己学习时实现的demo&…

eclipse maven jetty插件方式启动项目

2019独角兽企业重金招聘Python工程师标准>>> 1. 2.点击run即可启动项目 参考:maven命令具体含义请自行百度.例子:maven clean的作用 / maven djetty 转载于:https://my.oschina.net/u/3146772/blog/1576710