经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
Java的原型设计模式其实真的不难
来源:jb51  时间:2022/3/29 14:17:54  对本文有异议

原型设计模式

我们知道在有些程序设计中,程序内有大量相同或相似对象的创建问题,如果用传统的构造函数或者重新去new来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效。也就是我们当有一个原型的对象后,如果还需要一个或多个相同或者相似的对象,我们就也可以采用原型模式来设计。

举例说明:

在之前文章中讲的的可乐,我们知道可乐有很多配料,当刚研究出配方的时候我们去生产可乐,就需要往水里加各种各样的配料(相当于构造函数,然后传入参数),当之后才去生产可乐如果还是采用这种构造方法来生成的话,很麻烦且需要资源。我们把已经配好的作为一个可乐浓缩液,下次直接使用这个浓缩液就可以了(这就是原型设计模式里面的复制,直接复制浓缩液这个对象就可以)

1、原型设计模式的定义

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。

类型: 创建型

2、原型设计模式的优缺点

优点:

1.Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良

2.可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程

缺点:

1.需要为每一个类都配置一个 clone 方法 (浅克隆

2.clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则

3.当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当

3、原型模式的结构

结构由三部分组成:

  • 抽象原型类:规定了具体原型对象必须实现的接口
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象

在这里插入图片描述

4、浅克隆和深克隆的区别 

  • 浅克隆: 创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
  • 深克隆: 创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址

在这里插入图片描述

5、原型设计模式的简单代码实现

首先我们先来一个简单的原型模式

有一个具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象

  1. /**
  2. *
  3. *具体原型类,需要实现Cloneable接口
  4. */
  5. public class RealizeType implements Cloneable{
  6.  
  7. RealizeType(){
  8. System.out.println("具体原型类创建成功");
  9. }
  10.  
  11. public Object Clone() throws CloneNotSupportedException {
  12. System.out.println("具体原型类复制成功");
  13. return (RealizeType)super.clone();
  14. }
  15. }
  16.  

我们先来看一下需要实现Cloneable接口里面有什么?

在这里插入图片描述

其实这个接口里面什么都没有,只是一个代码规范而已

测试类:

  1. /**
  2. * 测试类:
  3. * 第一个类对象通过new来创建
  4. * 第二个对象通过clone()的方法来创建
  5. * 最后判断两个对象地址是否一致
  6. */
  7. public class Test {
  8. public static void main(String[] args) throws CloneNotSupportedException {
  9. RealizeType realizeType1 = new RealizeType();
  10. RealizeType realizeType2 = (RealizeType) realizeType1.Clone();
  11. boolean a = realizeType1==realizeType2;
  12. System.out.println("两个对象地址是否相等:" + a);
  13. }
  14. }
  15.  

如果两个对象的地址是一样的,说明没有复制成功,若地址不一样,则复制成功:

  1. 具体原型类创建成功具体原型复制成功两个对象地址是否相等:false

这样通过Clone()的方法复制了原型对象

6、原型设计模式的案例

公司里面每个阶段都会颁发荣誉,但是我们知道荣誉证书这个对象的模板已经确定好了,是固定不变的,我们只需要写入不同的信息即可:姓名、部门、获得的荣誉信息等等

奖状类:

  1. /**
  2. * 奖状荣誉类:相当于具体原型类,可以被克隆使用
  3. */
  4. public class Honor implements Cloneable{
  5.  
  6. String Department; //部门
  7. String name; //姓名
  8. String info; //获奖信息
  9.  
  10. //构造方法
  11. public Honor(String college, String name, String info) {
  12. this.Department = college;
  13. this.name = name;
  14. this.info = info;
  15. }
  16.  
  17. //getset
  18.  
  19. public String getCollege() {
  20. return Department;
  21. }
  22.  
  23. public void setCollege(String college) {
  24. this.Department = college;
  25. }
  26.  
  27. public String getName() {
  28. return name;
  29. }
  30.  
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34.  
  35. public String getInfo() {
  36. return info;
  37. }
  38.  
  39. public void setInfo(String info) {
  40. this.info = info;
  41. }
  42.  
  43. @Override
  44. public String toString() {
  45. return "奖状{" +
  46. "恭喜" + Department+
  47. "部门" + name +
  48. "同志获得" + info +
  49. '}';
  50. }
  51.  
  52. public Object clone() throws CloneNotSupportedException {
  53. System.out.println("荣誉拷贝成功!");
  54. return (Honor)super.clone();
  55. }
  56. }
  57.  

测试类:

  1. public class test {
  2. public static void main(String[] args) throws CloneNotSupportedException {
  3. Honor h1 = new Honor("销售部","张三","最佳销售");
  4. //第一个对象通过new来创建
  5. System.out.println(h1.toString());
  6.  
  7. //通过clone来拷贝
  8. Honor h2 = (Honor) h1.clone();
  9.  
  10. //更换名字
  11. h2.setName("李四");
  12. System.out.println(h2.toString());
  13.  
  14. Honor h3 = (Honor) h1.clone();
  15. h3.setInfo("最佳员工");
  16. h3.setName("王五");
  17. h3.setCollege("人事部");
  18. System.out.println(h3.toString());
  19.  
  20. }
  21. }
  22.  
  23.  

输出:

奖状{恭喜销售部部门张三同志获得最佳销售}
荣誉拷贝成功!
奖状{恭喜销售部部门李四同志获得最佳销售}
荣誉拷贝成功!
奖状{恭喜人事部部门王五同志获得最佳员工}

通过原型设计模式的方法,我们在创建相似对象的时候,就不需要使用构造函数new一个新对象,通过clone的方法即可,也可以任意修改参数(使用get/set)

7、原型设计模式的应用场景

1.对象之间相同或相似,即只是个别的几个属性不同的时候

2.创建对象成本较大,比如初始化时间长,需要优化资源等

3.创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性

4.系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值

在这里插入图片描述

在Java框架Spring中原型设计模式应用的也很多,所以这个模式还是有很多用处的

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注w3xue的更多内容!

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

本站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号