Java设计模式之创建型:原型模式
一、什么是原型模式:
原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。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设计模式之创建型:原型模式相关推荐
- Java设计模式之创建型-建造者模式 (Builder)
- Java设计模式之创建型:建造者模式
一.什么是建造者模式: 建造者模式将复杂产品的创建步骤分解在在不同的方法中,使得创建过程更加清晰,从而更精确控制复杂对象的产生过程:通过隔离复杂对象的构建与使用,也就是将产品的创建与产品本身分离开来, ...
- 设计模式(23):创建型-原型模式(Prototype)
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...
- Java设计模式之创建型:单例模式
一.什么是单例模式: 单例模式可以确保系统中某个类只有一个实例,该类自行实例化并向整个系统提供这个实例的公共访问点,除了该公共访问点,不能通过其他途径访问该实例.单例模式的优点在于: 系统中只存在一个 ...
- 【设计模式_青春版】创建型|原型模式
文章目录 原型模式(创建型) 原型模型的概念 一.实现Cloneable接口 二.实现自定义的顶层接口 java中的浅拷贝 Java中深拷贝 一.改造克隆方法 二.序列化与反序列化 总结 原型模式(创 ...
- Java设计模式之创建型模式
一.创建型模式 1.工厂模式[Factory] 定义:工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式. 普通工厂:工厂是具体的,产品是抽象的.[学习难度:★★☆☆☆,使用 ...
- java设计模式之创建型设计模式
创建型设计模式: 抽象工厂(Abstract Factory): 用途:提供一个接口以创建一系列相关或相互依赖的对象,而无需指定具体的类. 场景: 一个系统要独立于它的产品的创建. 一个系统要由多个产 ...
- 设计模式之创建型——工厂模式(3种)
→23种设计模式大纲 三种工厂模式 →23种设计模式大纲 定义 分类 1)简单工厂 UML类图 2)工厂方法 UML类图 3)抽象工厂 UML类图 总结 定义 将创建对象这一复杂的过程交由工厂控制,通 ...
- JAVA设计模式(14) —行为型模板方法模式(Template Method)
1 定义: 模板方法模式(Template Method) Define the skeleton of an algorithm in anoperation, deferring some ste ...
最新文章
- JS函数式编程概念理解:函子(Functor)
- android四大组件五大存储六大布局,物联网研报:物联网进入规模化应用时代
- HDU Problem - 5918 Sequence I
- 将windows系统装到USB存储设备
- 如何有效的压缩虚拟磁盘
- [转]如何删除图片链接的蓝色边框?
- python之event【事件】
- ios 中文输入法 完成事件_让聊天更方便 百度输入法开启AI助聊功能
- Android 黑色样式menu
- 微信话术自动回复机器人软件
- excel使用mysql数据库查询语句_如何通过Excel查询MySQL数据库
- FireBug使用方法
- ART加载OAT文件的过程分析
- easyui 行编辑中上传附件
- 简单明了理解交叉验证
- 电脑桌面提醒事项软件哪些可以定时弹出窗口提醒
- Linux发行版:CentOS、Ubuntu、RedHat、Android、Tizen、MeeGo
- 《用户至上:用户研究方法与实践(原书第2版)》一1.1 什么是用户体验
- linux添加理由,Linux 首次引入 nftables,你可能会喜欢 nftables 的理由
- java写wss,JAVA模拟WebSocket客户端,支持wss ssl证书
热门文章
- PW Live 直播 | 北邮博士生纪厚业:异质图神经网络之模型和应用
- HAN:基于双层注意力机制的异质图深度神经网络
- 今晚直播 | 平安人寿资深算法工程师姚晓远:对话生成模型的探析与创新
- Spring注释详解
- tkinter 布局_第八弹:读者问有tkinter的资料吗?
- springboot redis 刷新时间_「SpringBoot实战」SpringCache + Redis实现数据缓存
- Sklearn 损失函数如何应用到_Sklearn库主要模块功能简介
- HttpClient:绕开https证书(三)
- LeetCode 36 有效的数独
- LeetCode 20 有效的括号