设计模式学习笔记---原型模式prototype(Java版)
2015-02-28 22:21
891 查看
一、场景
克隆羊多利
二、本质
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式节约时间。就是java中的克隆技术,以某个对象为原型,复制出新的对象。新的对象具备原型对象的特点。效率高,避免了重新执行构造过程的步骤。
克隆类似于new,但不同于new.new创建新的对象属性采用的是默认值。克隆出的对象的属性值完全和原型对象相同。并且克隆出的新对象不会影响原型对象。然后,再修改克隆对象的值。
三、具体操作
实现Cloneable接口
重写Object的clone方法。
四、示例
1、浅克隆
2、深克隆
3、利用序列化和反序列化实现深克隆
4、测试
运行结果:
new创建的时间:10358
clone创建的时间:10
原型模式很少单独出现,一般是和工厂模式一起出现,通过clone方法创建一个对象,然后由工厂模式搭配起来。
创建者模式(都是用来创建对象)
单例模式***
保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
工厂模式
简单工厂***
用来生产同一等级中的任意产品。(修改已有代码)
工厂方法
用来生产同一等级结构中的任意产品。
抽象工厂
用来增加产品族的全部产品。
建造者模式
分离了对象子组件的单独构造和装配。从而构造出复杂的对象。
原型模式***
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
克隆羊多利
二、本质
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式节约时间。就是java中的克隆技术,以某个对象为原型,复制出新的对象。新的对象具备原型对象的特点。效率高,避免了重新执行构造过程的步骤。
克隆类似于new,但不同于new.new创建新的对象属性采用的是默认值。克隆出的对象的属性值完全和原型对象相同。并且克隆出的新对象不会影响原型对象。然后,再修改克隆对象的值。
三、具体操作
实现Cloneable接口
重写Object的clone方法。
四、示例
1、浅克隆
package com.lgd.prototype; import java.util.Date; public class LowSleep implements Cloneable{ private String nameString; private Date birthday; public LowSleep() { // TODO Auto-generated constructor stub } public LowSleep(String nameString, Date birthday) { super(); this.nameString = nameString; this.birthday = birthday; } @Override protected Object clone() throws CloneNotSupportedException { Object object = super.clone(); //直接调用object对象的clone()方法 return object; } public String getNameString() { return nameString; } public void setNameString(String nameString) { this.nameString = nameString; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
package com.lgd.prototype; import java.sql.Date; /** * 测试原型模式(浅克隆) * @author Administrator * 克隆 ---> 对象不同,但是内容一样。其中的内容可以修改。 */ public class ClientLowcopy { public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(12324354543543L); LowSleep s1 = new LowSleep("大羊", date); System.out.println(s1); System.out.println(s1.getNameString()); System.out.println(s1.getBirthday()); date.setTime(132432432423L);//修改时间 System.out.println(s1.getBirthday()); System.out.println("------------"); LowSleep s2 = (LowSleep) s1.clone();//浅克隆 System.out.println(s2); System.out.println(s2.getNameString()); System.out.println(s2.getBirthday()); System.out.println("------------"); s2.setNameString("小羊"); System.out.println(s2.getNameString()); /*********区别:浅克隆************/ date.setTime(1000L);//s1 s2 一起修改 System.out.println(s1.getBirthday()); System.out.println(s2.getBirthday()); /*********************/ s2.setBirthday(new Date(2314324324324L));//只修改了s2 System.out.println(s1.getBirthday()); System.out.println(s2.getBirthday()); s1.setNameString("巨羊"); System.out.println(s1.getNameString()); System.out.println(s2.getNameString()); } }
2、深克隆
package com.lgd.prototype; import java.util.Date; public class DeepSleep implements Cloneable{ private String nameString; private Date birthday; public DeepSleep() { // TODO Auto-generated constructor stub } public DeepSleep(String nameString, Date birthday) { super(); this.nameString = nameString; this.birthday = birthday; } @Override protected Object clone() throws CloneNotSupportedException { Object object = super.clone(); //直接调用object对象的clone()方法 //添加如下代码实现深复制 DeepSleep s = (DeepSleep) object; s.birthday = (Date) this.birthday.clone();//将属性也进行克隆 return object; } public String getNameString() { return nameString; } public void setNameString(String nameString) { this.nameString = nameString; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
package com.lgd.prototype; import java.sql.Date; public class ClientDeepcopy { public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(12324354543543L); DeepSleep s1 = new DeepSleep("大羊", date); System.out.println(s1); System.out.println(s1.getNameString()); System.out.println(s1.getBirthday()); date.setTime(132432432423L);//修改时间 System.out.println(s1.getBirthday()); System.out.println("------------"); DeepSleep s2 = (DeepSleep) s1.clone();//深克隆 s2对象的birthday是一个新对象。 System.out.println(s2); System.out.println(s2.getNameString()); System.out.println(s2.getBirthday()); System.out.println("------------"); s2.setNameString("小羊"); System.out.println(s2.getNameString()); /*********区别:深克隆************/ date.setTime(1000L);//s1修改 ,s2不变 System.out.println(s1.getBirthday()); System.out.println(s2.getBirthday()); /*********************/ s2.setBirthday(new Date(2314324324324L));//s1不变 ,s2修改 System.out.println(s1.getBirthday()); System.out.println(s2.getBirthday()); s1.setNameString("巨羊"); System.out.println(s1.getNameString()); System.out.println(s2.getNameString()); } }
3、利用序列化和反序列化实现深克隆
package com.lgd.prototype; import java.io.Serializable; import java.util.Date; public class LowSleep implements Cloneable,Serializable{ private static final long serialVersionUID = 1L; private String nameString; private Date birthday; public LowSleep() { // TODO Auto-generated constructor stub } public LowSleep(String nameString, Date birthday) { super(); this.nameString = nameString; this.birthday = birthday; } @Override protected Object clone() throws CloneNotSupportedException { Object object = super.clone(); //直接调用object对象的clone()方法 return object; } public String getNameString() { return nameString; } public void setNameString(String nameString) { this.nameString = nameString; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
package com.lgd.prototype; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.sql.Date; /** * 测试原型模式(利用序列化与反序列化实现深克隆) * @author Administrator */ public class ClientSerializable { public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException { Date date = new Date(12324354543543L); LowSleep s1 = new LowSleep("大羊", date); System.out.println(s1); System.out.println(s1.getNameString()); System.out.println(s1.getBirthday()); //LowSleep s2 = (LowSleep) 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); LowSleep s2 = (LowSleep) ois.readObject(); System.out.println("------------"); s2.setNameString("小羊"); System.out.println(s2); System.out.println(s2.getNameString()); System.out.println(s2.getBirthday()); System.out.println("------------"); /*********区别:序列与反序列化************/ date.setTime(1000L); System.out.println(s1.getBirthday()); System.out.println(s2.getBirthday()); /*********************/ } }
4、测试
package com.lgd.prototype; /** * 测试普通new方式创建对象和clone方式创建对象的效率差异 * 如果需要短时间创建大量对象,并且new比较耗时,则可以考虑原型模式。 * @author liguodong * */ public class ClientTest { 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 CloneNotSupportedException { 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 { // TODO Auto-generated method stub return super.clone(); } }
运行结果:
new创建的时间:10358
clone创建的时间:10
原型模式很少单独出现,一般是和工厂模式一起出现,通过clone方法创建一个对象,然后由工厂模式搭配起来。
创建者模式(都是用来创建对象)
单例模式***
保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
工厂模式
简单工厂***
用来生产同一等级中的任意产品。(修改已有代码)
工厂方法
用来生产同一等级结构中的任意产品。
抽象工厂
用来增加产品族的全部产品。
建造者模式
分离了对象子组件的单独构造和装配。从而构造出复杂的对象。
原型模式***
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
相关文章推荐
- java 设计模式学习笔记(8) - 原型模式
- 设计模式学习笔记(十一)—Prototype原型模式
- 设计模式学习笔记——Prototype原型模式
- java学习笔记-设计模式6(原型模式)
- 步步为营 .NET 设计模式学习笔记 五、Prototype(原型模式)
- 设计模式学习笔记(四)——Prototype原型
- 设计模式学习笔记--Prototype原型模式
- 学习笔记——JAVA设计模式<4>原型模式
- java设计模式学习笔记--原型模式(浅克隆和深克隆)
- 设计模式学习笔记——原型(Prototype)框架
- 设计模式学习笔记_原型模式(prototype)
- HeadFirst 设计模式学习笔记19--原型(Prototype)模式拾零
- java设计模式学习笔记-原型模式
- 设计模式学习笔记——Prototype原型模式
- 步步为营 .NET 设计模式学习笔记 五、Prototype(原型模式)
- java 设计模式学习笔记四 prototype模式
- 【HeadFirst 设计模式学习笔记】18 原型(Prototype)模式拾零
- 设计模式学习笔记--工厂(Factory)、建造(Builder)和原型(Prototype)
- java/android 设计模式学习笔记(11)---原型模式
- 设计模式学习笔记(六)——Prototype原型模式