Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 287|回复: 0

[默认分类] Java源码阅读基础----设计模式----原型模式

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-4-24 11:26:50 | 显示全部楼层 |阅读模式



          
      原型模式(prototype):就是说的java中的克隆技术,指定一个原型来克隆,克隆后的对象拥有原型中所有的属性。说到克隆大家肯定会想到Object类中的clone方法或者
      cloneable接口。


          大家可以看看我写的关于Object类的文章:
      https://blog.csdn.net/lyz812672598/article/details/80017802


          说到拷贝,又要不说另一个概念:浅拷贝和深拷贝。




          浅拷贝:通俗点说就是对原型对象引用的拷贝(打个比喻,就像一个人站在一面镜子面前,你看着镜子里的人和站在镜子面前的人好像确实变成了两个人,长个也一摸一样,但是“原型人”动一下,镜子中的人也会动一下,有依赖关系)。


           深拷贝:对原型对象中所有成员的值进行拷贝,直到最底层(打个比喻,就像双胞胎一样,你看着两个人一模一样,但是他们之间不存在依赖关系,一个人闭眼睛了,另一个人照样睁着眼睛)。

         话不多说,直接上代码,用代码说话。
    1. [/code]
    2. [code]public class Student {
    3.     public String name;   public Integer age;   public String sex; }
    复制代码
    1. [/code]
    2. [code]
    复制代码
    1. public class ProtoType implements Cloneable {
    2.     public Integer high;   public Student student;   @Override  protected Object clone() throws CloneNotSupportedException {
    3.         ProtoType obj = (ProtoType)super.clone();  return obj;   }
    4. }
    复制代码
    1. [/code]
    2. [code]
    复制代码
    1. [/code]
    2. [code]public class ProtoTypeTest {
    3.     public static void main(String[] args) {
    4.         Student student = new Student();  student.name = "马云云";  student.age = 18;  student.sex = "男";  ProtoType protoType = new ProtoType();  protoType.high = 180;  protoType.student = student;  ProtoType protoType1 = null;  try {
    5.             protoType1 = (ProtoType) protoType.clone();  } catch (CloneNotSupportedException e) {
    6.             e.printStackTrace();  }
    7.         student.name = "雷小军";  student.age = 21;  student.sex = "女";  System.[i]out[/i].println("原型对象地址:");  System.[i]out[/i].println(protoType);  System.[i]out[/i].println(protoType1);  System.[i]out[/i].println("原型对象成员地址:");  System.[i]out[/i].println(protoType.student);  System.[i]out[/i].println(protoType1.student);  System.[i]out[/i].println(protoType.student.name);  System.[i]out[/i].println(protoType1.student.name);  System.[i]out[/i].println(protoType.student.age);  System.[i]out[/i].println(protoType1.student.age);  System.[i]out[/i].println(protoType.student.sex);  System.[i]out[/i].println(protoType1.student.sex);  }
    8. }
    复制代码
    1. [/code]
    2.   原型对象地址: com.design.pattern.proto.ProtoType@140e19d com.design.pattern.proto.ProtoType@17327b6 原型对象成员地址: com.design.pattern.proto.vo.Student@14ae5a5 com.design.pattern.proto.vo.Student@14ae5a5 雷小军 雷小军 21 21 女 女
    3.   Process finished with exit code 0
    4.       通过代码输出发现,我们用了clone方法(未重写,用的是父类方法)后,虽然按照原型给我们确实复制了一个出来,但是克隆出来的对象里面的对象压根还是原型里面的对象,有兴趣的同学可以把”student“中的属性改一改,看看是否最后输出结果是否一样。
    5.   所以我们发现浅拷贝不能完全摆脱原型的控制,原型中的成员就是拷贝后的对象成员。
    6.       
    7.   那么我们怎么做到深克隆呢?刚刚也说了只要把对象的成员也拷贝一份即可,直到最底层。
    8.   
    9. [code]
    复制代码
    1. public class Student implements Cloneable {
    2.     public String name;   public Integer age;   public String sex;   @Override  protected Student clone() throws CloneNotSupportedException {
    3.         return (Student) super.clone();  }
    4. }
    复制代码
    1. [/code]
    2. [code]public class ProtoType implements Cloneable {
    3.     public Integer high;   public Student student;   @Override  protected Object clone() throws CloneNotSupportedException {
    4.         ProtoType obj = (ProtoType)super.clone();  obj.student = student.clone();  return obj;   }
    5. }
    复制代码
    1. [/code]
    2.   原型对象地址: com.design.pattern.proto.ProtoType@140e19d com.design.pattern.proto.ProtoType@17327b6 原型对象成员地址: com.design.pattern.proto.Student@14ae5a5 com.design.pattern.proto.Student@131245a 雷小军 马云云 21 18 女 男
    3.   Process finished with exit code 0
    4.      通过输出我们看到了,原型对象成员的改变,对克隆对象的影响消失了,即没有依赖关系了。但是上面的方法也有一个很大的缺陷,就是
    5. 如果我们对象里的结构非常复杂的话,那么我们重写clone方法的代价就特别大,所以不推荐大家这么去做。那更简单的方法是什么呢?
    6. 就是我们java里的序列化,可以帮我们达到深克隆的目的。看代码:
    7. [code]
    复制代码
    1. public class Student implements Serializable {
    2.     public String name;   public Integer age;   public String sex; }
    复制代码
    1. [/code]
    2. [code]public class ProtoType implements Cloneable,Serializable {
    3.     public Integer high;   public Student student;   @Override  protected Object clone() throws CloneNotSupportedException{
    4.         Object obj = null;  try {
    5.             obj = deepClone();  } catch (Exception e) {
    6.             e.printStackTrace();  }
    7.         return obj;  }
    8.     private Object deepClone() throws Exception {
    9.         ByteArrayOutputStream bos = new ByteArrayOutputStream();  ObjectOutputStream oos = new ObjectOutputStream(bos);  oos.writeObject(this);  ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  ObjectInputStream ois = new ObjectInputStream(bis);  ProtoType obj = (ProtoType) ois.readObject();  return obj;  }
    10. }
    复制代码
    [code][/code]

      原型对象地址: com.design.pattern.proto.ProtoType@10bedb4 com.design.pattern.proto.ProtoType@1eba861 原型对象成员地址: com.design.pattern.proto.Student@10455d6 com.design.pattern.proto.Student@1480cf9 雷小军 马云云 21 18 女 男


      Process finished with exit code 0
         
    从输出可以看出,同样可以达到深克隆的目的。其实原型模式主要是为了让我们避免多次创建对象(因为每创建一次对象就需要初始化一次,同样Objec文章里讲到),避免了其构造过程中引起系统的消耗。












    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-16 20:39 , Processed in 0.411148 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表