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

浅复制

 package com.test.prototype;

 import java.util.Date;

 /**
* 浅复制
*/
public class Sheep implements Cloneable{//Cloneable为标记接口
private String sname;
private Date birthday; @Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();//直接调用object对象的clone()方法
return obj;
} public Sheep() {
} public Sheep(String sname, Date birthday) {
super();
this.sname = sname;
this.birthday = birthday;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
 package com.test.prototype;

 import java.util.Date;
/**
* 测试原型模式(浅复制)
*/
public class Client {
public static void main(String[] args) throws Exception {
Date date = new Date(3333332323L);
Sheep s1 = new Sheep("少利", date);
Sheep s2 = (Sheep) s1.clone(); System.out.println(s1);
System.out.println(s1.getSname());
System.out.println(s1.getBirthday());
date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改
System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday() s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}

控制台输出: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

深复制

 package com.test.prototype;

 import java.util.Date;

 /**
* 深复制
*/
public class Sheep2 implements Cloneable{//Cloneable为标记接口
private String sname;
private Date birthday; @Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();//直接调用object对象的clone()方法 //添加如下代码实现深复制(Deep Clone)
Sheep2 s = (Sheep2) obj;
s.birthday = (Date) this.birthday.clone();//属性克隆! return obj;
} public Sheep2() {
} public Sheep2(String sname, Date birthday) {
super();
this.sname = sname;
this.birthday = birthday;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
 package com.test.prototype;

 import java.util.Date;
/**
* 测试原型模式(深复制)
*/
public class Client2 {
public static void main(String[] args) throws Exception {
Date date = new Date(3333332323L);
Sheep2 s1 = new Sheep2("少利", date);
Sheep2 s2 = (Sheep2) s1.clone(); System.out.println(s1);
System.out.println(s1.getSname());
System.out.println(s1.getBirthday());
date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改
System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday() s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}

控制台输出: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设计模式】_原型模式、反序列化实现深复制、效率对比、创建型模式总结 
利用序列化和反序列化技术实现深复制

 package com.test.prototype;

 import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* 原型模式(使用序列化和反序列化的方式实现深复制)
*/
public class Client3 {
public static void main(String[] args) throws Exception {
Date date = new Date(3333332323L);
Sheep s1 = new Sheep("少利", date); System.out.println(s1);
System.out.println(s1.getSname());
System.out.println(s1.getBirthday()); // Sheep s2 = (Sheep) s1.clone();
//使用序列化和反序列化实现深复制
//序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(s1);
byte[] bytes = bos.toByteArray(); //反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis); Sheep s2 = (Sheep) ois.readObject();//深复制的对象 System.out.println("修改原型对象的属性值");
date.setTime(332324355555555L);
System.out.println(s1.getBirthday()); s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}

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

 package com.test.prototype;
/**
* 测试普通new方式创建对象和clone方式创建对象的效率差异!
* 如果需要短时间创建大量对象,并且new的过程比较耗时,则可以考虑使用原型模式!
*/
public class Client4 { public static void testNew(int size){
long start = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
Laptop t = new Laptop();
}
long end = System.currentTimeMillis();
System.out.println("new的方式创建耗时:" + (end - start));
} public static void testClone(int size) throws CloneNotSupportedException{
long start = System.currentTimeMillis();
Laptop t = new Laptop();
for (int i = 0; i < size; i++) {
Laptop temp = (Laptop) t.clone();
}
long end = System.currentTimeMillis();
System.out.println("clone的方式创建耗时:" + (end - start));
} public static void main(String[] args) throws Exception {
testNew(1000);
testClone(1000);
}
} class Laptop implements Cloneable{//笔记本电脑
public Laptop(){
try{
Thread.sleep(10);//模拟创建对象耗时的过程!
}catch(InterruptedException e){
e.printStackTrace();
}
} @Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();//直接调用object对象的clone()方法
return obj;
}
}

控制台输出:

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

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

创建型模式的总结: 

【GOF23设计模式】原型模式的更多相关文章

  1. 10. 星际争霸之php设计模式--原型模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. PHP 设计模式 原型模式(Prototype)之深/浅拷贝

      看PHP 设计模式 原型模式(Prototype)时,衍生出一个扩展问题之 原型拷贝的浅拷贝和深拷贝问题(不管写Java还是写PHP还是写JS时都多多少少遇到过对象拷贝问题)   比如写前端页面时 ...

  3. PHP设计模式 原型模式(Prototype)

    定义 和工厂模式类似,用来创建对象.但实现机制不同,原型模式是先创建一个对象,采用clone的方式进行新对象的创建. 场景 大对象的创建. 优点 1.可以在运行时刻增加和删除产品 2.可以改变值或结构 ...

  4. 【设计模式】Java设计模式 - 原型模式

    [设计模式]Java设计模式 - 原型模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...

  5. C#设计模式-原型模式

    在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在内存中分配 ...

  6. [工作中的设计模式]原型模式prototype

    一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.pro ...

  7. 我的Java设计模式-原型模式

    "不好意思,我是卧底!哇哈哈哈~"额......自从写了上一篇的观察者模式,就一直沉浸在这个角色当中,无法自拨.昨晚在看<使徒行者2>,有一集说到啊炮仗哥印钞票,我去, ...

  8. C++设计模式——原型模式

    什么是原型模式? 在GOF的<设计模式:可复用面向对象软件的基础>中是这样说的:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.这这个定义中,最重要的一个词是“拷贝”,也就 ...

  9. Java设计模式—原型模式

    原型设计模式是一种比较简单的设计模式,在项目中使用的场景非常多. 个人理解: 原型模式实现了对Java中某个对象的克隆功能,即该对象的类必须implements实现Cloneable接口来标识为可被克 ...

  10. 设计模式——原型模式(Prototype)

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.——DP UML类图 模式说明 如果把在一张纸上手写一篇简历的过程看成是类的实例化过程,那么通过原型模式创建对象的过程就是拿着这张纸到复印 ...

随机推荐

  1. jquery重写一个对话框

    (原文来自博客园 wuchao.cnblogs.com) 写一个简单的基于jquery的对话框 css: #dialog { border:solid 1px #CCC; width:300px; h ...

  2. CLR via C#深解笔记四 - 方法、参数、属性

    实例构造器和类(引用类型) 构造器(constructor)是允许将类型的实例初始化为良好状态的一种特殊方法.构造器方法在“方法定义元数据表”中始终叫.ctor. 创建一个引用类型的实例时: #1, ...

  3. 【转载】linux内核启动android文件系统过程分析

    主要介绍linux 内核启动过程以及挂载android 根文件系统的过程,以及介绍android 源代码中文件系统部分的浅析. 主要源代码目录介绍Makefile (全局的Makefile)bioni ...

  4. MFC设置静态文本框,编辑框等控件背景和字体颜色

    在MFC类库提供了CWnd::OnCtlColor函数,在工作框架的子窗口被重画时将调用该成员函数.因此可以重载WM_CTLCOLOR消息的响应函数.此函数的原型:afx_msg HBRUSH OnC ...

  5. 【转】Linux下svn常用指令

    转自: http://blog.csdn.net/myarrow/article/details/8110858 1.将文件checkout到本地目录svn checkout path(path是服务 ...

  6. Git 文件比较

    Git 的三个作业场: 工作区(Work Tree) 项目根目录下 .git 目录以外所有区域,是编辑项目文件的地方. 缓存区(Index) 工作区文件必须先保存在缓存区,之后从缓存区保存到仓库. 仓 ...

  7. Surface Shader

    Surface Shader: (1)必须放在SubShdader块,不能放在Pass内部: (2)#pragma sufrace surfaceFunction lightModel [option ...

  8. 斐波那契堆(二)之 C++的实现

    概要 上一章介绍了斐波那契堆的基本概念,并通过C语言实现了斐波那契堆.本章是斐波那契堆的C++实现. 目录1. 斐波那契堆的介绍2. 斐波那契堆的基本操作3. 斐波那契堆的C++实现(完整源码)4.  ...

  9. MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...

  10. Direct3D11学习:(四)计时和动画

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 接触过游戏开发的人都知道,在游戏中,计时器是一个非常重要的工具,用来精确地控制游戏帧数和动画的播放.要正确实现动 ...