《大话设计模式》书中描述原型(Prototype)模式:

原型模式(Prototype):用用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

原型模式(Prototype Pattern)结构图

这种形式涉及到三个角色:

客户(Client)角色:客户类提出创建对象的请求。

抽象原型(Prototype)角色:这是一个抽象角色,通常由Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。

具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。

源代码:

抽象原型角色

public interfacePrototype{/*克隆自身的方法

@return 一个从自身克隆出来的对象*/

publicObject clone();

}

具体原型角色

public class ConcretePrototype1 implementsPrototype {publicPrototype clone(){//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了

Prototype prototype = newConcretePrototype1();returnprototype;

}

}

public class ConcretePrototype2 implementsPrototype {publicPrototype clone(){//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了

Prototype prototype = newConcretePrototype2();returnprototype;

}

}

客户端角色

public classClient {/*持有需要使用的原型接口对象*/

privatePrototype prototype;/*构造方法,传入需要使用的原型接口对象*/

publicClient(Prototype prototype){this.prototype =prototype;

}public voidoperation(Prototype example){//需要创建原型接口的对象

Prototype copyPrototype =prototype.clone();

}

}

Java中的克隆方法

Java的所有类都是从java.lang.object类继承而来的,而Object类提供protected Object clone()方法对对象进行复制,子类当然也可以把这个方法置换掉,提供满足自己需要的复制方法。对象的复制有一个基本问题,就是对象通常都有对其他的对象的引用。当使用Object类的clone()方法来复制一个对象时,此对象对其他对象的引用也同时会被复制一份。

Java语言提供的Cloneable接口只起一个作用,就是在运行时期通知Java虚拟机可以安全地在这个类上使用clone()方法。通过调用这个clone()方法可以得到一个对象的复制。由于Object类本身并不实现Cloneable接口,因此如果所考虑的类没有实现Cloneable接口时,调用clone()方法会抛出CloneNotSupportedException异常。

克隆满足的条件

clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的。一般而言,clone()方法满足一下的描述:

对任何的对象x,都有:x.clone()!=x。换而言之,克隆对象与原对象不是同一个对象。

对任何的对象x,都有:x.clone().getClass() == x.getClass(),换而言之,克隆对象与原对象的类型一样。

如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。

在Java语言的API中,凡是提供了clone()方法的类,都满足上面的这些条件。Java语言的设计师在设计自己的clone()方法时,也应当遵守三个条件。一般来说,上面的三个条件中的前两个时必需的,而第三个是可选的。

浅克隆和深克隆

无论你是自己实现克隆方法,还是采用Java提供的克隆方法,都存在一个浅度克隆和深度克隆的问题。

浅度克隆:只负责克隆按值传递的数据(比如基本数据类型、String类型),而不复制它所引用的对象,换而言之,被复制对象的所有变量都含有与原来的对象相同值,而所有的对其他对象的引用都仍然指向原来的对象。

深度克隆:除了浅度克隆的值外,还负责克隆引用类型的数据。那些引用其他的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换而言之,深度克隆把复制的对象都复制了一遍,而这种对引用到的对象的复制叫做间接复制。

利用序列化实现深度克隆

把对象写到流里的过程是序列化(Serialization)过程;而把对象从流中读出来的过程则叫反序列化(Deserialization)过程。应该指出的是,写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。

在Java语言里深度克隆一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的拷贝)写到一个流里(序列化),再从流里读回来(反序列化),便可以重建对象。

public Object deepClone() throwsIOException, ClassNotFoundException{//将对象写到流里

ByteArrayOutputStream bos = newByteArrayOutputStream();

ObjectOutputStream oos= newObjectOutputStream(bos);

oos.writeObject(this);//从流里读回来

ByteArrayInputStream bis = newByteArrayInputStream(bos.toByteArray());

ObjectInputStream ois= newObjectInputStream(bis);returnois.readObject();

}

这样做的前提就是对象以及对象内部所有引用到的对象都是可序列化的,否则,就需要仔细考察那些不可序列化的对象可否设成transient,从而将之排除在复制过程之外。

浅度克隆显然比深度克隆更容易实现,因为Java语言的所有类都会继承一个clone()方法,而这个clone()方法所做的正式浅度克隆。有一些对象,比如线程(Thread)对象或Socket对象,是不能简单复制或共享的。不管是使用浅度克隆还是深度克隆,只要涉及这样的间接对象设成transient而不予以复制;或者由程序自行创建出相当的同种对象,权且当做复制件使用。

参考资料:

java 复印件效果_简历复印—原型模式相关推荐

  1. Java设计模式之创建型:原型模式

    一.什么是原型模式: 原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.UML类图如下: 原型模式的核心是就是原型类 Prototype,Prototype ...

  2. java 肌汉模式_设计模式之原型模式详解(附源代码)

    原型模式(Prototype Pattern) 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. ...

  3. java 设计模式 prototype_Java设计模式之Prototype原型模式

    一.场景描述 创建型模式中,从工厂方法模式,抽象工厂模式,到建造者模式,再到原型模式,我的理解是,创建对象的方式逐步从编码实现转向内存对象处理. 例如,在"仪器数据采集器"的子类/ ...

  4. 原型模式 java 深浅_java学习笔记之原型模式及深浅拷贝

    一.原型模式的基本介绍 在聊原型模式之前,我们来思考一个小问题,传统的方式我们是如何克隆对象呢? 那我们以多利羊(Sheep)为例,来说明上述这个问题,具体代码见下面: 多利羊(Sheep) publ ...

  5. Java设计模式之(四)——原型模式

    1.什么是原型模式 Specify the kinds of objects to create using a prototypical instance,and create new object ...

  6. php设计模式原型模式,原型模式_设计模式_设计模式之原型模式 - Lane Blog

    10 8 Clicks: 6614 Date: 2014-04-21 21:48:35 Power By 李轩Lane 原型模式提取重复功能,避免了程序员喜欢复制粘贴的坏习惯.设计模式中的原型模式就是 ...

  7. java 图片效果_使用Java进行图片底片化效果处理

    使用java代码读取图片,并进行底片化处理 util importjava.awt.image.BufferedImage;importjava.io.File;importjava.util.Arr ...

  8. java幻灯片效果_在PowerPoint 中,幻灯片切换效果是指(  )。

    [判断题]在用户需求分析时观察用户手工操作过程不是为了模拟手工操作过程,而是为了获取第一手资料,并从中提取出有价值的需求. [单选题]在 E-R模型中,包含以下基本成分 [简答题]课程9月作业题目 有 ...

  9. 小谈原型模式 | 深复制与浅复制

    小谈原型模式 | 深复制与浅复制 一.前言 二.原型模式的运用场景和解释 三.先看看这几个简单的程序 每次新建一份简历我都new一下 直接引用不复制了(错误) 不想复制的时候new对象了 对副本进行简 ...

最新文章

  1. 还在用if(obj!=null)做非空判断?带你快速上手Optional实战性理解!
  2. QT数据库使用案列【联系人】-- 使用sqlite和QStringListModel
  3. python学习干货教程(5):#!/usr/bin/python
  4. 腾讯微博qq说说备份导出工具_10年了!腾讯微博宣布关停,宜昌90后的青春不再!...
  5. codeforces 269B Greenhouse Effect
  6. 一幅漫画揭示了项目研发过程中存在的问题,太形象了
  7. 64.判断当前线程是否是主线程
  8. 【图论训练】最小拓扑序
  9. 宇宙大爆炸是不是一个黑洞的大爆炸?
  10. html鼠标互动旋转立方体,css3 transform及原生js实现鼠标拖动3D立方体旋转的示例介绍...
  11. Activity与Service之间交互并播放歌曲
  12. 六种实现元素水平居中
  13. 【游戏开发】游戏开发书籍汇总
  14. Spring中的AOP原理
  15. Linux命令对应的英文及整体学习法
  16. js练习:模拟京东快递单号查询
  17. Unity材质偏移(贴图纹理偏移)实现流动效果【记录一下】
  18. Microservices 基础理论
  19. mc洪磊-2012经典语言大合集 音乐无处不在 老婆无人替代 好听音乐 就用酷狗
  20. Win11怎么关闭休眠?Win11禁止休眠设置方法

热门文章

  1. vue element table 相关页面跳转实例代码
  2. 5 大场景深度探讨何为 Serverless 架构模式?
  3. “加薪”、“洗手间”都不能提?亚马逊内部员工通讯 App 曝光
  4. 有一个写代码很厉害的老板是怎样一种体验?
  5. 第八届开源操作系统年度技术会议(OS2ATC)在京召开, 百位科技菁英到场共鉴“开源协作”
  6. 百度智能云“云+AI”新战略年终答卷,PaddlePaddle累计开发者数量265万人
  7. 任正非:华为明年至少招8000名应届生;苹果开发 Google 搜索的替代;NumPy 1.19.3发布|极客头条
  8. 无代码时代下,程序员不够用了!
  9. 一站式快速实现应用现代化,IBM Cloud Pak做对了什么? | 技术公开课
  10. 几行代码构建全功能对象检测模型,这位杜克大学学生做到了!