原型模式(clone?)

Prototype pattern refers to creating duplicate object while keeping performance in mind. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

参考:

  1. tutorialspoint | prototype_pattern
  2. 博客园 | 原型模式
  3. 博客园 | Java深拷贝与序列化

原型模式是通过复制已有对象来快速创建新对象的方法,它适用于创建那些实例化很慢的对象,比如数据库连接对象,在创建好这样的对象后,我们可以缓存一份,下次需要这种对象时,我们可以直接返回一个该对象的拷贝。

使用场景

  1. 需要大量相似对象时,如果在类中需要大量相似的对象,并且这些对象中有很多属性都是一样的,只有个别属性需要定制时,可以使用原型模式,因为直接从内从中复制对象比new一个新对象的性能要高得多。
  2. 如果一个对象的实例化过程很耗时耗力,可以使用原型模式。

Java Cloneable接口

Java中提供了一个标记接口Cloneable,类如果实现了这个接口就可以使用Object类中定义的clone方法

如果没有实现Cloneable接口,直接调用clone()会抛出CloneNotSupportedException

Object clone()会返回当前对象的一个浅拷贝

深拷贝和浅拷贝

根据不同的对象类型,拷贝的内容也各不相同:

  1. 基本数据类型,如int,char等,直接拷贝
  2. 对于字符串,拷贝时只复制引用,当字符串的值改变时,会从字符串池中重新生成新的字符串,最终结果和拷贝值一样
  3. 对于对象,拷贝时只复制引用,如果要复制值,需要使用深拷贝
public class Out implements Cloneable{private String outName;private In in;public Out(String outName) {this.outName = outName;}public void setIn(In in) {this.in = in;}@Overridepublic String toString() {return "Out{" +"outName='" + outName + '\'' +", in=" + in +'}';}@Overrideprotected Out clone() throws CloneNotSupportedException {return (Out) super.clone();}public static void main(String[] args) {Out out = new Out("out");In in = new In("in name");out.setIn(in);Out out1 = null;try {// in 是一个object类型,所以在调用clone()时只复制了in的引用out1 = out.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}assert out1 != null;// 改变out1.in的name也会改变out中in的nameout1.in.setName("out1 in");System.out.println(out);System.out.println(out1);}
}
/*
Out{outName='out', in=In{name='out1 in'}}
Out{outName='out', in=In{name='out1 in'}}
*/

深拷贝 DeepCopy

Java中实现深拷贝可以手动拷贝object类型的属性,但如果这个类型中还有object类型,就会很麻烦。

@Override
protected DCOut clone() throws CloneNotSupportedException {DCOut copy = (DCOut) super.clone();In copyIn = (In) this.in.clone();copy.setIn(copyIn);return copy;
}

还可以使用Serializable接口,通过序列化,将堆中的对象数据信息复制一份到堆外,再反序列化成新的克隆对象

import java.io.*;public class DeepClone implements Serializable {private Object obj;public DeepClone(Object obj){this.obj = obj;}public Object deepClone() {Object result = null;//序列化ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = null;try {oos = new ObjectOutputStream(baos);oos.writeObject(obj);} catch (IOException e) {e.printStackTrace();}// 反序列化ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream  ois = null;try {ois = new ObjectInputStream(bais);result = ois.readObject();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}return result;}
}

python中的深拷贝和浅拷贝

In [1]: import copyIn [2]: a = [i for i in range(10)]In [3]: b = copy.copy(a)In [4]: a is b
Out[4]: FalseIn [5]: c = [[1, 2], [3, 4]]In [6]: d = copy.copy(c)In [7]: d is c
Out[7]: FalseIn [8]: d[0] is c[0]
Out[8]: TrueIn [9]: e = copy.deepcopy(c)In [10]: e[0] is c[0]
Out[10]: FalseIn [11]:

python内置的copy模块提供了深拷贝和浅拷贝的功能,python中浅拷贝只会拷贝父对象,不会拷贝父对象内部的子对象

python切片属于浅拷贝

《大话设计模式》里简历的例子

package pers.junebao.prototype_pattern;import pers.junebao.prototype_pattern.deep_copy.DeepClone;import java.io.Serializable;public class Resume implements Cloneable, Serializable {private String name;private String education;private String sex;Resume(String name) {this.name = name;}public void setName(String name) {this.name = name;}public void setEducation(String education) {this.education = education;}public void setSex(String sex) {this.sex = sex;}public void print(){System.out.println("name: " + this.name);System.out.println("sex : " + this.sex);System.out.println("education: " + this.education);}@Overridepublic Resume clone() {Resume resume = null;// 深拷贝resume = (Resume) DeepClone.deepClone(this);return resume;}
}
package pers.junebao.prototype_pattern;public class Main {public static void main(String[] args) {Resume resume = new Resume("JuneBao");resume.setSex("男");resume.setEducation("本科");Resume resume1 = resume.clone();resume1.setSex("女");resume.print();resume1.print();}
}

GitHub | 完整代码

【设计模式 06】原型模式(克隆??)相关推荐

  1. 【学习笔记】设计模式-原型模式/克隆模式(Prototype)

    文章目录 0 设计模式 1 原型模式 2 实现思路 2.1 浅克隆 2.2 深克隆 3 需要的类 4 具体实现 4.1 浅克隆 4.2 深克隆 5 思维导图 6 示例源码地址 最后 0 设计模式 不了 ...

  2. 【GOF23设计模式】原型模式

    [GOF23设计模式]原型模式 来源:http://www.bjsxt.com/  一.[GOF23设计模式]_原型模式.prototype.浅复制.深复制.Cloneable接口  浅复制 1 pa ...

  3. 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)

    [索引页] [源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:webabcd 介绍 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. ...

  4. 在王者荣耀角度下分析面向对象程序设计B中23种设计模式之原型模式

    · 原型模式在王者荣耀中的应用 · 一.简述 在王者荣耀中,克隆模式算是一个人气比较高的娱乐模式了,因为该模式下双方可以各有五个一模一样的英雄,可以带给玩家不同的游戏体验,特别是有一些比较好玩的英雄, ...

  5. 二十三种设计模式之原型模式

    今天继续探讨GOF二十三种设计模式的原型模式,原型模式也是属于创建型模式的一种 原型模式通俗的讲就是对象复制的过程,即通过一个原型对象,我可以得到一个该对象的克隆. 下面来看下原型模式的第一种写法-- ...

  6. C#设计模式(6)——原型模式(Prototype Pattern)

    一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...

  7. Java设计模式之原型模式

    原型模式(Prototype Pattern)属于对象创建型模式,通过克隆指定原型对象创建新对象. 优点: 效率高:原型模式可以简化创建对象的创建过程,通过克隆一个已有的实例可以提高新实例的创建效率: ...

  8. 设计模式回顾——原型模式(C++)

    文章目录 1 前言 2 什么是原型模式 2.1 原型模式组成 2.2 原型模式UML图 2.3 原型模式作用 3 原型模式优缺点 4 什么地方使用原型模式 5 原型模式实现 6 原型模式与构造函数 1 ...

  9. 设计模式之 原型模式

    原型模式应用场景举例:  GG和MM经常在QQ上聊天,但是GG打字的速度慢如蜗牛爬行,每次MM在瞬间完成恢复或者问候是,GG都会很紧张的去尽力快速打字,尽管如此,还是让MM有些不高心,MM说回复信息这 ...

  10. 教你如何一篇博客读懂设计模式之—--原型模式

    教你如何一篇博客读懂设计模式之----原型模式 what:是什么 原型模式: 用于创建重复的对象,既不用一个属性一个属性去set和get,又不影响性能,原型模式产生的对象和原有的对象不是同一个实例,他 ...

最新文章

  1. Python导出Excel文件
  2. java基本数据类型_Java面试题Java中有几种基本数据类型?它们分别占多大字节?...
  3. DB2 乱码
  4. 秦汉考场科目三路线图_我在青竹湖考场考科三的一些分享
  5. 使用linux实验总结及心得,实验心得
  6. spring mvc-基础-简单程序
  7. ZOJ Problem Set - 1292 Integer Inquiry
  8. autocad 二次开发 拆分图纸_2,手动创建CAD二次开发项目--AutoCAD二次开发(2020版)...
  9. python初体验——单/双/三引号的用法
  10. 服务器的cd驱动器怎么修改盘符,更改dvd驱动器盘符,cd驱动器盘符改
  11. 数据挖掘中的模式发现(七)GSP算法、SPADE算法、PrefixSpan算法
  12. matplotlib入门基础(五)轴坐标范围 轴刻度比例 轴刻度
  13. OSI七层模型及各层功能概述
  14. 用 Dotfuscator 混淆web api应用
  15. 计算机科学 期刊怎么样,《计算机科学》杂志怎么样?提交的好吗?
  16. python处理文本文件
  17. 【Allegro学习笔记】表面贴装封装设计过程——0402封装
  18. 微信小程序自定义组件:带未读数目的tabBar按钮(小红点+带未读数目)
  19. 前端学习 DAY04
  20. 2023年跨境电商行业研究报告

热门文章

  1. 解决: IDEA 代码 commit 后,Local Changes 中代码依旧在,提交失败,报错:is out of date
  2. 最好理解的: spring ioc原理讲解,强烈推荐!
  3. 安装Ubunutu音频视频库
  4. underscore.js源码研究(5)
  5. OAuth 2.0(网转)
  6. python pip处理
  7. 在TextView中实时显示数据
  8. 将中文标点符号替换成英文标点符号
  9. 公司应该如果管理员工?
  10. xpath-helper: 谷歌浏览器安装xpath helper 插件