设计模式之建造型-原型模式(5)
来源:互联网 发布:2017程序员 编辑:程序博客网 时间:2024/05/18 01:12
今天介绍原型模式,也是最后一个建造型设计模式
定义:通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的方法来创建出更多的新对象。
定义很简单,就是通过实例制定种类,通过拷贝创建对象,该模式适用于以下场景1,对象的创建十分复杂。2在运行的过程中并不知道对象的具体类型,可以使用原型模式来
创建一个相同类型的对象出来。
在Java中,实现原型模式很简单,即实现cloneable接口,然后使用object类提供的clone方法进行拷贝,而拷贝又分为浅拷贝和深度拷贝下面我们来用代码实现浅拷贝
public class Student implements Cloneable { public StudentMessage studentMessage; public void setStudentMessage (StudentMessage studentMessage){ this.studentMessage=studentMessage; } @Override public Student clone() { Student student= null; try { student = (Student) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return student; }}public class StudentMessage{ String name; String ID; public StudentMessage(String name, String ID) { this.name = name; this.ID = ID; }}
测试类
public class Test { public static void main(String[] args) { Student phoneA=new Student(); phoneA.setStudentMessage(new StudentMessage("zhangsan","1234")); Student phoneB = phoneA.clone(); System.out.print("phoneA:"+phoneA.toString()); System.out.print(" phoneB:"+phoneB.toString()); System.out.print(" StudentMessageA:"+phoneA.studentMessage.toString()); System.out.print(" StudentMessageB:"+phoneB.studentMessage.toString()); }}
结果输出:
上面即为最简单的原型模式的实现,其中浅拷贝的基本变量都会重新创建,而引用类型,指向还是原来的对象所指向,上面例子中的student还是指向原来的。值得注意的是,运用clone()方法创建出来的对象的构造方法并不会执行。
深拷贝
深拷贝会使引用类型都重新创建,在java中有两种写法,一种为需要克隆对象所使用的所有引用类型都实现cloneable接口,然后重写object类提供的clone方法进行拷贝。
public class StudentMessage implements Cloneable{ String name; String ID; public StudentMessage(String name, String ID) { this.name = name; this.ID = ID; } @Override protected StudentMessage clone() throws CloneNotSupportedException { return (StudentMessage) super.clone(); }}public class Student implements Cloneable { public StudentMessage studentMessage; public void setStudentMessage (StudentMessage studentMessage){ this.studentMessage=studentMessage; } @Override public Student clone() { Student student= null; try { student = (Student) super.clone(); studentMessage = student.studentMessage.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return student; }}
测试:
public class Test { public static void main(String[] args) { Student phoneA=new Student(); phoneA.setStudentMessage(new StudentMessage("zhangsan","1234")); Student phoneB = phoneA.clone(); System.out.print("phoneA:"+phoneA.toString()); System.out.print(" phoneB:"+phoneB.toString()); System.out.print(" StudentMessageA:"+phoneA.studentMessage.toString()); System.out.print(" StudentMessageB:"+phoneB.studentMessage.toString()); }}
输出:
phoneA:com.wujie.demo.clone.Student@266474c2
phoneB:com.wujie.demo.clone.Student@6f94fa3e
StudentMessageA:com.wujie.demo.clone.StudentMessage@5e481248
StudentMessageB:com.wujie.demo.clone.StudentMessage@66d3c617
我们可以看到,其中引用类型被重新创建了,但是,假如我们引用的类型里,又有新的引用类似的时候,用这种方法完成深度拷贝会无比的麻烦,这个时候我们利用序列化进行拷贝
public class StudentMessage implements Serializable{ String name; String ID; public StudentMessage(String name, String ID) { this.name = name; this.ID = ID; }}public class Student implements Serializable { public StudentMessage studentMessage; public void setStudentMessage (StudentMessage studentMessage){ this.studentMessage=studentMessage; } @Override public Student clone() { Student student=null; try { ByteArrayOutputStream bos=new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bais=new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois=new ObjectInputStream(bais); student = (Student) ois.readObject(); } catch (IOException e) { e.printStackTrace(); }catch (ClassNotFoundException e) { e.printStackTrace(); } return student; }}
我们注意到,所有的引用类都要继承serializable接口才可以序列化
测试:
public class Test { public static void main(String[] args) { Student phoneA=new Student(); phoneA.setStudentMessage(new StudentMessage("zhangsan","1234")); Student phoneB = phoneA.clone(); System.out.print("phoneA:"+phoneA.toString()); System.out.print(" phoneB:"+phoneB.toString()); System.out.print(" StudentMessageA:"+phoneA.studentMessage.toString()); System.out.print(" StudentMessageB:"+phoneB.studentMessage.toString()); }}
输出:
phoneA:com.wujie.demo.clone.Student@355da254
phoneB:com.wujie.demo.clone.Student@12edcd21
StudentMessageA:com.wujie.demo.clone.StudentMessage@4dc63996
StudentMessageB:com.wujie.demo.clone.StudentMessage@34c45dca
可以看到,利用序列化的方式可以相对简单的完成深度克隆,序列化就是将对象写进流的过程,写进流的过程会对原有对象进行拷贝克隆
到此就将5种创建型模式一一介绍完毕。
- 设计模式之建造型-原型模式(5)
- 设计模式之建造型-建造者模式(4)
- TypeScript设计模式之单例、建造者、原型
- TypeScript设计模式之单例、建造者、原型
- 设计模式之Builder(建造模式)
- 设计模式之十三 建造者模式(建造小人)
- 创建型:设计模式之建造模式(四)
- 设计模式之建造型-单例模式(1)
- 设计模式之建造型-简单工厂模式(2)
- 设计模式之建造型-抽象工厂模式(3)
- 设计模式之--建造模式
- 设计模式之建造模式
- 设计模式之建造模式
- 设计模式之建造模式
- (5)设计模式之建造者模式(创建型模式)
- (4)设计模式之原型模式(创建型模式)
- 设计模式二(建造者、原型、桥接)
- 设计模式笔记(十一)--建造者模式、原型模式、单例模式
- 用python创建你自己的命令行地址簿程序
- Oracle 高水位(HWM: High Water Mark) 说明
- 从一大堆数字中找出几个最大的数
- 高考重要还是身体重要?高考生为避生理期吃避孕药!
- windows下安装和使用mongodb
- 设计模式之建造型-原型模式(5)
- 关于MySQL变量innodb_rollback_on_timeout一些讨论
- R语言基于RJDBC实现oracle/mysql数据库操作
- python 常用函数
- JS弹出提示框
- Bootstrap学习之五:图片轮播
- Python次位面——获取命令行参数
- 20170525_WPSC++实习_电话面试
- 磁疗有用吗?恒定磁场对骨折愈合的影响