经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
创建型模式————原型模式(2.3)
来源:cnblogs  作者:noneplus  时间:2019/8/15 12:15:10  对本文有异议

什么是原型模式?

简单来说,通过复制的方式创建对象。(被复制的对象可以理解为模板)


原型模式的应用场景

复杂结构对象的创建。

复杂结构对象:可以理解为对象里面还有对象。


【举个栗子】:点外卖的收货地址


收货地址包括姓名,电话和住址。第一次点外卖的时候需要完整的填写这些信息,但是之后点的过程基本上是不用再重新填写这些信息的。试想一下,每次下单之前都要填一遍姓名,电话,详细地址(假设省市已经定位好了)。头大.....而这个场景,正是原型模式的用武之地。

点外卖之前复制上一次填写的地址,直接下单;或者手机号出现变更,修改一下直接更新到模板即可。

原型模式的本质是创建一个对象模板,然后通过复制的方式实现复用。


深拷贝(复杂对象一波带走)

在深拷贝之前,简单聊一下浅拷贝。

以上述收货地址为例,如果只涉及到姓名,电话这些基本数据类型(浅拷贝与深拷贝是基本没有区别的),但是如果涉及到地址这样的引用类型。浅拷贝就会出现问题。浅拷贝对于引用对象,只复制其引用地址。所以复制出来的对象和被复制的对象会指向同一个值。假设你想建立两个收货模板,地址是不同的,那么就只能使用深拷贝了。


撸段代码试试看:

思路:

1.创建Info类和Address类继承Serializable接口,为了后面实现序列化写入内存。(实现平台无关性)

2.Info类还需要继承Cloneable接口,并重写clone()方法,注:protected改为public

3.在clone()方法中添加写入内存和读取的逻辑

4.Info info1 = (Info) info.clone();创建对象,并可做灵活修改。

  1. import java.io.*;
  2. class Address implements Serializable
  3. {
  4. private String province;
  5. private String city;
  6. private String Street;
  7. private String door_number;
  8. public Address(String province, String city, String street, String door_number) {
  9. this.province = province;
  10. this.city = city;
  11. Street = street;
  12. this.door_number = door_number;
  13. }
  14. public String getProvince() {
  15. return province;
  16. }
  17. public void setProvince(String province) {
  18. this.province = province;
  19. }
  20. public String getCity() {
  21. return city;
  22. }
  23. public void setCity(String city) {
  24. this.city = city;
  25. }
  26. public String getStreet() {
  27. return Street;
  28. }
  29. public void setStreet(String street) {
  30. Street = street;
  31. }
  32. public String getDoor_number() {
  33. return door_number;
  34. }
  35. public void setDoor_number(String door_number) {
  36. this.door_number = door_number;
  37. }
  38. @Override
  39. public String toString() {
  40. return "Address{" +
  41. "province='" + province + '\'' +
  42. ", city='" + city + '\'' +
  43. ", Street='" + Street + '\'' +
  44. ", door_number='" + door_number + '\'' +
  45. '}';
  46. }
  47. }
  48. class Info implements Cloneable, Serializable //1.创建一个外卖信息类,继承Cloneable(可复制),Serializable(可序列化)
  49. {
  50. private String name;
  51. private String number;
  52. Address address;
  53. public String getName() {
  54. return name;
  55. }
  56. public void setName(String name) {
  57. this.name = name;
  58. }
  59. public String getNumber() {
  60. return number;
  61. }
  62. public void setNumber(String number) {
  63. this.number = number;
  64. }
  65. public Address getAddress() {
  66. return address;
  67. }
  68. public void setAddress(Address address) {
  69. this.address = address;
  70. }
  71. public Info(String name, String number, Address address) {
  72. this.name = name;
  73. this.number = number;
  74. this.address = address;
  75. }
  76. @Override
  77. public String toString() {
  78. return "Info{" +
  79. "name='" + name + '\'' +
  80. ", number='" + number + '\'' +
  81. ", address=" + address +
  82. '}';
  83. }
  84. @Override
  85. public Object clone() throws CloneNotSupportedException { //2.重写clone方法,并把protected换成public
  86. ByteArrayOutputStream out = new ByteArrayOutputStream();
  87. try {
  88. ObjectOutputStream oos = new ObjectOutputStream(out);
  89. oos.writeObject(this); //写入内存
  90. oos.close();
  91. byte[] bytes = out.toByteArray();
  92. InputStream in = new ByteArrayInputStream(bytes);
  93. ObjectInputStream ois = new ObjectInputStream(in);
  94. Object clone = ois.readObject(); //读取内存
  95. ois.close();
  96. return clone;
  97. } catch (Exception e) {
  98. throw new RuntimeException(e);
  99. }
  100. }
  101. }
  102. /*
  103. clone()方法直接复制在内存中已经创建对象的二进制,效率极高!(不需要调用构造器)
  104. protected native Object clone() throws CloneNotSupportedException;
  105. native修饰的方法直接调用底层的C语言
  106. */
  107. public class MyInfo
  108. {
  109. public static void main(String[] args) throws CloneNotSupportedException {
  110. Info info = new Info("shadow","18116207310",new Address("上海","浦东新区","振南路","355"));
  111. System.out.println(info);
  112. Info info1 = (Info) info.clone(); //3.复制加强转
  113. System.out.println(info1);
  114. System.out.println("//修改电话:");
  115. Info info2 = (Info) info.clone();
  116. info2.setNumber("123456789");
  117. System.out.println(info2);
  118. System.out.println("//修改地址:");
  119. Info info3 = (Info) info.clone();
  120. info3.getAddress().setStreet("西语街");
  121. info3.getAddress().setDoor_number("666");
  122. System.out.println(info3);
  123. }
  124. }

输出结果:

1565608154656

原文链接:http://www.cnblogs.com/noneplus/p/11342048.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号