一、什么是原型模式:

原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。UML类图如下:

原型模式的核心是就是原型类 Prototype,Prototype 类需要具备以下两个条件:

  • (1)实现 Cloneable 接口:在 Java 中 Cloneable 接口的作用就是在运行时通知虚拟机可以安全地在实现了 Cloneable 接口的类上使用 clone() 方法,只有在实现了 Cloneable 的类才可以被拷贝,否则在运行时会抛出 CloneNotSupportedException 异常。
  • (2)重写 Object 类中的 clone() 方法:Java 中所有类的父类都是 Object,Object 中有一个clone() 方法用于返回对象的拷贝,但是其作用域 protected,一般的类无法调用,因此,Prototype 类需要将 clone() 方法的作用域修改为 public。

原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式。在实际应用中,原型模式很少单独出现。经常与其他模式混用,他的原型类Prototype也常用抽象类来替代。

二、原型模式的优点与适用场景:

(1)原型模式比 new 方式创建对象的性能要好的多,因为 Object 类的 clone() 方法是一个本地方法,直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显;

(2)简化对象的创建;

所以原型模式适合在重复地创建相似对象的场景使用,比如在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且也可以提供系统的整体性能。

三、注意事项:

(1)使用原型模式复制对象不会调用类的构造函数,对象是通过调用 Object 类的 clone() 方法来完成的,它直接在内存中复制数据。不但构造函数不会执行,甚至连访问权限都对原型模式无效。单例模式中,需要将构造函数的访问权限设置为 private,但是 clone() 方法直接无视构造方法的权限,所以单例模式与原型模式是冲突的,在使用时需要注意。

(2)深拷贝与浅拷贝。Object 类的 clone() 方法只会拷贝对象中的基本的数据类型(8种基本数据类型 byte,char,short,int,long,float,double,boolean 和对应的封装类),对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。

  • 浅拷贝:只克隆对象中的基本数据类型,而不会克隆数组、容器、引用对象等。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。如果变量为String字符串,则拷贝其引用地址,但是在修改的时候,它会从字符串池中重新生成一个新的字符串,原有的字符串对象保持不变。
  • 深拷贝:把要克隆的对象所引用的对象都克隆了一遍。

有关深拷贝与浅拷贝的更多内容,可以参考这篇文章:Java基础篇:对象拷贝:clone方法 以及 序列化_张维鹏的博客-CSDN博客

四、实现代码:

public abstract class Prototype implements Cloneable {protected ArrayList<String> list = new ArrayList<String>();@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}public abstract void show();
}
public class ShallowClone extends Prototype {@Overridepublic Prototype clone(){Prototype prototype = null;try {prototype = (Prototype)super.clone();}catch (CloneNotSupportedException e) {e.printStackTrace();}return prototype;}@Overridepublic void show(){System.out.println("浅克隆");}
}
public class DeepClone extends Prototype {@SuppressWarnings("unchecked")@Overridepublic Prototype clone() {Prototype prototype = null;try {prototype = (Prototype)super.clone();}catch (CloneNotSupportedException e) {e.printStackTrace();}prototype.list = (ArrayList<String>) this.list.clone();return prototype;}@Overridepublic void show(){System.out.println("深克隆");}
}

由于ArrayList不是基本类型,所以成员变量list,不会被拷贝,需要我们自己实现深拷贝,幸运的是Java提供的大部分的容器类都实现了Cloneable接口。所以实现深拷贝并不是特别困难。

public class Client {public static void main(String[] args) {ShallowClone cp = new ShallowClone();ShallowClone clonecp = (ShallowClone) cp.clone();clonecp.show();System.out.println(clonecp.list == cp.list);DeepClone cp2 = new DeepClone();DeepClone clonecp2 = (DeepClone) cp2.clone();clonecp2.show();System.out.println(clonecp2.list == cp2.list);}
}

运行结果:

浅克隆
true
深克隆
false

设计模式系列文章:

Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)

Java设计模式之创建型:建造者模式

Java设计模式之创建型:单例模式

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

Java设计模式之结构型:适配器模式

Java设计模式之结构型:装饰器模式

Java设计模式之结构型:代理模式

Java设计模式之结构型:桥接模式

Java设计模式之结构型:外观模式

Java设计模式之结构型:组合模式

Java设计模式之结构型:享元模式

Java设计模式之行为型:策略模式

Java设计模式之行为型:模板方法模式

Java设计模式之行为型:责任链模式

Java设计模式之行为型:观察者模式

Java设计模式之行为型:访问者模式

Java设计模式之行为型:中介者模式

Java设计模式之行为型:命令模式

Java设计模式之行为型:状态模式

Java设计模式之行为型:备忘录模式

Java设计模式之行为型:迭代器模式

Java设计模式之行为型:解释器模式


原博客链接:

JAVA设计模式之原型模式_一个本科小生的奋斗史-CSDN博客_java设计模式原型模式

设计模式-创建型-原型模式(Prototype)_vapy's blog-CSDN博客

Java设计模式之创建型:原型模式相关推荐

  1. Java设计模式之创建型-建造者模式 (Builder)

  2. Java设计模式之创建型:建造者模式

    一.什么是建造者模式: 建造者模式将复杂产品的创建步骤分解在在不同的方法中,使得创建过程更加清晰,从而更精确控制复杂对象的产生过程:通过隔离复杂对象的构建与使用,也就是将产品的创建与产品本身分离开来, ...

  3. 设计模式(23):创建型-原型模式(Prototype)

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...

  4. Java设计模式之创建型:单例模式

    一.什么是单例模式: 单例模式可以确保系统中某个类只有一个实例,该类自行实例化并向整个系统提供这个实例的公共访问点,除了该公共访问点,不能通过其他途径访问该实例.单例模式的优点在于: 系统中只存在一个 ...

  5. 【设计模式_青春版】创建型|原型模式

    文章目录 原型模式(创建型) 原型模型的概念 一.实现Cloneable接口 二.实现自定义的顶层接口 java中的浅拷贝 Java中深拷贝 一.改造克隆方法 二.序列化与反序列化 总结 原型模式(创 ...

  6. Java设计模式之创建型模式

    一.创建型模式 1.工厂模式[Factory] 定义:工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式. 普通工厂:工厂是具体的,产品是抽象的.[学习难度:★★☆☆☆,使用 ...

  7. java设计模式之创建型设计模式

    创建型设计模式: 抽象工厂(Abstract Factory): 用途:提供一个接口以创建一系列相关或相互依赖的对象,而无需指定具体的类. 场景: 一个系统要独立于它的产品的创建. 一个系统要由多个产 ...

  8. 设计模式之创建型——工厂模式(3种)

    →23种设计模式大纲 三种工厂模式 →23种设计模式大纲 定义 分类 1)简单工厂 UML类图 2)工厂方法 UML类图 3)抽象工厂 UML类图 总结 定义 将创建对象这一复杂的过程交由工厂控制,通 ...

  9. JAVA设计模式(14) —行为型模板方法模式(Template Method)

    1 定义: 模板方法模式(Template Method) Define the skeleton of an algorithm in anoperation, deferring some ste ...

最新文章

  1. JS函数式编程概念理解:函子(Functor)
  2. android四大组件五大存储六大布局,物联网研报:物联网进入规模化应用时代
  3. HDU Problem - 5918 Sequence I
  4. 将windows系统装到USB存储设备
  5. 如何有效的压缩虚拟磁盘
  6. [转]如何删除图片链接的蓝色边框?
  7. python之event【事件】
  8. ios 中文输入法 完成事件_让聊天更方便 百度输入法开启AI助聊功能
  9. Android 黑色样式menu
  10. 微信话术自动回复机器人软件
  11. excel使用mysql数据库查询语句_如何通过Excel查询MySQL数据库
  12. FireBug使用方法
  13. ART加载OAT文件的过程分析
  14. easyui 行编辑中上传附件
  15. 简单明了理解交叉验证
  16. 电脑桌面提醒事项软件哪些可以定时弹出窗口提醒
  17. Linux发行版:CentOS、Ubuntu、RedHat、Android、Tizen、MeeGo
  18. 《用户至上:用户研究方法与实践(原书第2版)》一1.1 什么是用户体验
  19. linux添加理由,Linux 首次引入 nftables,你可能会喜欢 nftables 的理由
  20. java写wss,JAVA模拟WebSocket客户端,支持wss ssl证书

热门文章

  1. PW Live 直播 | 北邮博士生纪厚业:异质图神经网络之模型和应用
  2. HAN:基于双层注意力机制的异质图深度神经网络
  3. 今晚直播 | 平安人寿资深算法工程师姚晓远:对话生成模型的探析与创新
  4. Spring注释详解
  5. tkinter 布局_第八弹:读者问有tkinter的资料吗?
  6. springboot redis 刷新时间_「SpringBoot实战」SpringCache + Redis实现数据缓存
  7. Sklearn 损失函数如何应用到_Sklearn库主要模块功能简介
  8. HttpClient:绕开https证书(三)
  9. LeetCode 36 有效的数独
  10. LeetCode 20 有效的括号