设计模式之原型模式
来源:互联网 发布:linux的dd命令SD卡 编辑:程序博客网 时间:2024/06/18 08:07
1、核心本质:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2、应用场景:
-通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
3、原型模式实现:
-Cloneable接口和clone方法(不属于Cloneable接口,是Object类中的方法,通过override该方法实现拷贝)
-Prototype模式中实现起来最困难的地方就是内存复制操作,所幸在java中提供了clone()方法替我们做了绝大部分事情
4、浅复制与深复制的概念
浅复制:复制对象与原对象所有成员变量的值相等,包括引用成员变量(即复制对象与原对象引用成员变量都指向同一个对象)。
深复制:复制对象与原对象所有成员变量(除引用变量外)都相等,虽然引用变量的值不同,但引用变量指向的对象成员数据相等。
代码示例:
/** * 实体类(实现浅复制) * @author ly1 * */public class Car1 implements Cloneable,Serializable{ private String name; private Date cloneDate; public Car1(String name, Date cloneDate) { super(); this.name = name; this.cloneDate = cloneDate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCloneDate() { return cloneDate; } public void setCloneDate(Date cloneDate) { this.cloneDate = cloneDate; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }}
/** * 原型模式(浅复制) * @author ly1 * */public class Client1 { public static void main(String[] args) throws Exception { Date date = new Date(1231312312312L); Car1 c1 = new Car1("奥迪",date); Car1 c2 = (Car1) c1.clone(); System.out.println("修改前:"); System.out.println("c1-->date:"+c1.getCloneDate()); System.out.println("c2-->date:"+c2.getCloneDate()); date.setTime(917239817932172L); System.out.println("修改后:"); System.out.println("c1-->date:"+c1.getCloneDate()); System.out.println("c2-->date:"+c2.getCloneDate()); }}结果:修改前:c1-->date:Wed Jan 07 15:11:52 CST 2009c2-->date:Wed Jan 07 15:11:52 CST 2009修改后:c1-->date:Fri Mar 04 22:18:52 CST 31036c2-->date:Fri Mar 04 22:18:52 CST 31036
import java.util.Date;/** * 实体类(实现深复制) * @author ly1 * */public class Car2 implements Cloneable{ private String name; private Date cloneDate; public Car2(String name, Date cloneDate) { super(); this.name = name; this.cloneDate = cloneDate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCloneDate() { return cloneDate; } public void setCloneDate(Date cloneDate) { this.cloneDate = cloneDate; } @Override protected Object clone() throws CloneNotSupportedException { //将对象的成员变量(除基本类型和String类型)也都克隆一份,实现深复制 Object clone = super.clone(); Car2 car = (Car2) clone; car.cloneDate = (Date) this.cloneDate.clone(); return car; }}
import java.util.Date;/** * 原型模式(浅复制) * @author ly1 * */public class Client2 { public static void main(String[] args) throws Exception { Date date = new Date(1231312312312L); Car2 c1 = new Car2(new String("奥迪"),date); Car2 c2 = (Car2) c1.clone(); System.out.println("修改前:"); System.out.println("c1-->date:"+c1.getCloneDate()); System.out.println("c2-->date:"+c2.getCloneDate()); date.setTime(917239817932172L); System.out.println("修改后:"); System.out.println("c1-->date:"+c1.getCloneDate()); //由于实现了深复制,改变对象c1的成员变量,c2的成员变量不改变 System.out.println("c2-->date:"+c2.getCloneDate()); }}结果:修改前:c1-->date:Wed Jan 07 15:11:52 CST 2009c2-->date:Wed Jan 07 15:11:52 CST 2009修改后:c1-->date:Fri Mar 04 22:18:52 CST 31036c2-->date:Wed Jan 07 15:11:52 CST 2009
5、使用序列化与反序列化实现深复制
/** * 使用序列化和反序列化技术实现深复制 * 要求实体类实现java.io.Serializable接口 * @author ly1 * */public class Client3 { public static void main(String[] args) throws Exception { Date date = new Date(12312312L); Car1 car = new Car1("宝马",date); //使用序列化和反序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(car); byte[] bytes = bos.toByteArray(); oos.flush(); oos.close(); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); Car1 car2 = (Car1) ois.readObject(); ois.close(); System.out.println(car); System.out.println(car2); System.out.println("原型:-->date" + car.getCloneDate()); System.out.println("克隆:-->date" + car2.getCloneDate()); System.out.println("修改前:"); System.out.println("c1-->date:"+car.getCloneDate()); System.out.println("c2-->date:"+car2.getCloneDate()); date.setTime(917239817932172L); System.out.println("修改后:"); System.out.println("c1-->date:"+car.getCloneDate()); System.out.println("c2-->date:"+car2.getCloneDate()); }}结果:Prototype.Car1@8ea9cf1Prototype.Car1@729f624a原型:-->dateThu Jan 01 11:25:12 CST 1970克隆:-->dateThu Jan 01 11:25:12 CST 1970修改前:c1-->date:Thu Jan 01 11:25:12 CST 1970c2-->date:Thu Jan 01 11:25:12 CST 1970修改后:c1-->date:Fri Mar 04 22:18:52 CST 31036c2-->date:Thu Jan 01 11:25:12 CST 1970
6、new方式与clone方式效率对比
/** * 测试new方式和clone()方式(原型模式)的效率 * @author ly1 * */public class Client4 { public static void testNew(){ long start = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { Rocket r = new Rocket(); } long end = System.currentTimeMillis(); System.out.println("new方式耗时:"+(end - start)+"ms"); } public static void testClone() throws Exception{ Rocket r = new Rocket(); long start = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { Rocket r1 = (Rocket) r.clone(); } long end = System.currentTimeMillis(); System.out.println("clone方式耗时:"+(end - start)+"ms"); } public static void main(String[] args) throws Exception { testNew(); testClone(); }}class Rocket implements Cloneable{ public Rocket(){ try { Thread.sleep(10); //线程休眠10ms,模拟创建对象耗时现象 } catch (InterruptedException e) { e.printStackTrace(); } } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }}结果:new方式耗时:10093msclone方式耗时:0ms
分析:
-很显然clone方式快得多,直接从内存复制。
-如果创建对象很耗时,可以采用原型模式。
0 0
- 设计模式之原型
- 设计模式之原型
- 设计模式 之 原型
- 设计模式之原型
- 设计模式之原型
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之-原型模式
- 设计模式之 原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之--原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- visio 画 弯曲 箭头 ( 波浪线 曲线)
- Objective-C---9---内存管理 补充
- 在MDI主窗口中设置图像背景
- Xcode Build Search Paths设置
- DLL库的Def
- 设计模式之原型模式
- 训练自己haar-like特征分类器并识别物体(2)
- 002-storm基本概念
- iOS绘图教程
- 我的BIOS之行(2)-Aptio BIOS Overview
- 智能优化算法小结
- jQuery获取循环出来的DOM节点
- 二级指针
- gcc 嵌入式汇编(asm)实现bsr(位扫描)指令