设计模式7 ——原型模式
一、原型模式的定义
Specifythekindsofobjectstocreateusingaprototypicalinstance,andcreatenewobjectsbycopyingthisprototype.(用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。)
二、原型模式的应用
1、原型模式的优点
性能优良原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
逃避构造函数的约束这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的。优点就是减少了约束,缺点也是减少了约束,需要大家在实际应用时考虑。
2、原型模式的缺点
需要为每个类配备一个克隆方法,而且该克隆方法位于这个类里面,当对已有的类进行改造时需要修改源代码,违背了开闭原则
在实现深度克隆的时需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用的时候,为了实现深度克隆,每一层对象的类都必须支持深度克隆,实现起来比较麻烦!
3、原型模式的使用场景
资源优化场景类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
性能和安全要求的场景通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
一个对象多个修改者的场景一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与Java融为一体,大家可以随手拿来使用。
三、原型模式的写法
重写clone实现深拷贝
public class DeepCloneable {public static void main(String[] args) throws CloneNotSupportedException {DeepObject deepObject = new DeepObject("deepName");deepObject.setCloneObjece(new CloneObjece("cloneObjeceName"));//两次输出hashcode不一致System.out.println(deepObject.getCloneObjece().hashCode());DeepObject cloneDeepObject = (DeepObject)deepObject.clone();System.out.println(cloneDeepObject.getCloneObjece().hashCode());}
}class DeepObject implements Cloneable{private String deepName;private CloneObjece cloneObjece;public DeepObject(String deepName) {this.deepName = deepName;}public CloneObjece getCloneObjece() {return cloneObjece;}public void setCloneObjece(CloneObjece cloneObjece) {this.cloneObjece = cloneObjece;}@Overridepublic String toString() {return "DeepObject [deepName=" + deepName + ", cloneObjece=" + cloneObjece + "]";}// 深拷贝方式一:使用clone方法@Overrideprotected Object clone() throws CloneNotSupportedException {Object clone = super.clone();DeepObject cloneDeepObject = (DeepObject)clone;cloneDeepObject.setCloneObjece((CloneObjece)cloneDeepObject.getCloneObjece().clone());return cloneDeepObject;}
}class CloneObjece implements Cloneable{private String cloneObjeceName;public CloneObjece(String cloneObjeceName) {this.cloneObjeceName = cloneObjeceName;}@Overridepublic String toString() {return "CloneObjece [cloneObjeceName=" + cloneObjeceName + "]";}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
对象序列化实现深拷贝
public class DeepCloneable {public static void main(String[] args) throws CloneNotSupportedException {DeepObject deepObject = new DeepObject("deepName");deepObject.setCloneObjece(new CloneObjece("cloneObjeceName"));//两次输出hashcode不一致System.out.println(deepObject.getCloneObjece().hashCode());DeepObject cloneDeepObject = (DeepObject)deepObject.deepClone();System.out.println(cloneDeepObject.getCloneObjece().hashCode());}
}class DeepObject implements Serializable{private static final long serialVersionUID = 1L;private String deepName;private CloneObjece cloneObjece;public DeepObject(String deepName) {this.deepName = deepName;}public CloneObjece getCloneObjece() {return cloneObjece;}public void setCloneObjece(CloneObjece cloneObjece) {this.cloneObjece = cloneObjece;}@Overridepublic String toString() {return "DeepObject [deepName=" + deepName + ", cloneObjece=" + cloneObjece + "]";}// 方式二 序列化public Object deepClone() {Object obj = null;// 准备流对象ByteArrayOutputStream bos = null;ObjectOutputStream oos = null;ByteArrayInputStream bis = null;ObjectInputStream ois = null;try {// 生成流对象,并进行序列化bos = new ByteArrayOutputStream();oos = new ObjectOutputStream(bos);oos.writeObject(this);// 反序列化bis = new ByteArrayInputStream(bos.toByteArray());ois = new ObjectInputStream(bis);obj = ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}finally {// 关闭流try {if(ois != null)ois.close();if(bis != null)bis.close();if(oos != null)oos.close();if(bos != null)bos.close();} catch (IOException e) {e.printStackTrace();}}return obj;}}class CloneObjece implements Serializable{private static final long serialVersionUID = 1L;private String cloneObjeceName;public CloneObjece(String cloneObjeceName) {this.cloneObjeceName = cloneObjeceName;}@Overridepublic String toString() {return "CloneObjece [cloneObjeceName=" + cloneObjeceName + "]";}
}
四、原型模式在源码中的应用
@Overridepublic Object clone() {return new Intent(this);}/*** Copy constructor.*/public Intent(Intent o) {this.mAction = o.mAction;this.mData = o.mData;this.mType = o.mType;this.mPackage = o.mPackage;this.mComponent = o.mComponent;this.mFlags = o.mFlags;if (o.mCategories != null) {this.mCategories = new ArraySet<String>(o.mCategories);}if (o.mExtras != null) {this.mExtras = new Bundle(o.mExtras);}if (o.mSourceBounds != null) {this.mSourceBounds = new Rect(o.mSourceBounds);}if (o.mSelector != null) {this.mSelector = new Intent(o.mSelector);}if (o.mClipData != null) {this.mClipData = new ClipData(o.mClipData);}}
可以看到,clone方法实际上在内部调用了new Intent(this); 而且是深拷贝。
设计模式7 ——原型模式相关推荐
- 【GOF23设计模式】原型模式
[GOF23设计模式]原型模式 来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_原型模式.prototype.浅复制.深复制.Cloneable接口 浅复制 1 pa ...
- 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)
[索引页] [源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:webabcd 介绍 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. ...
- 教你如何一篇博客读懂设计模式之—--原型模式
教你如何一篇博客读懂设计模式之----原型模式 what:是什么 原型模式: 用于创建重复的对象,既不用一个属性一个属性去set和get,又不影响性能,原型模式产生的对象和原有的对象不是同一个实例,他 ...
- 二十三种设计模式之原型模式
今天继续探讨GOF二十三种设计模式的原型模式,原型模式也是属于创建型模式的一种 原型模式通俗的讲就是对象复制的过程,即通过一个原型对象,我可以得到一个该对象的克隆. 下面来看下原型模式的第一种写法-- ...
- C#设计模式(6)——原型模式(Prototype Pattern)
一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...
- 设计模式回顾——原型模式(C++)
文章目录 1 前言 2 什么是原型模式 2.1 原型模式组成 2.2 原型模式UML图 2.3 原型模式作用 3 原型模式优缺点 4 什么地方使用原型模式 5 原型模式实现 6 原型模式与构造函数 1 ...
- 设计模式之 原型模式
原型模式应用场景举例: GG和MM经常在QQ上聊天,但是GG打字的速度慢如蜗牛爬行,每次MM在瞬间完成恢复或者问候是,GG都会很紧张的去尽力快速打字,尽管如此,还是让MM有些不高心,MM说回复信息这 ...
- 设计模式之原型模式(Prototype)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式包括:1.FactoryMethod(工厂方法模式):2.Abstract Factory(抽象工厂模式):3.Sin ...
- golang设计模式之原型模式
原型模式 wiki:原型模式是创建型模式的一种,其特点在于通过"复制"一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的"原型",这个 ...
- 【设计模式】原型模式 ( 概念简介 | 使用场景 | 优缺点 | 基本用法 )
文章目录 I . 原型模式 概念简介 II . 原型模式 使用场景 III . 原型模式 优缺点 IV . 原型模式 实现及 简单示例 I . 原型模式 概念简介 原型模式 : 用原型实例指定创建对象 ...
最新文章
- Markdown通用的常用语法说明
- 软件测试基础知识——适合初学者
- 2018面向对象程序设计(Java)第3周学习指导及要求
- SDWebImage源码阅读(九)SDWebImageDownloader
- python 正则匹配 条件太多怎么办_Python条件正则表达式
- 【Java心得总结六】Java容器中——Collection
- 程序员“离职小技巧”
- python 3.8.5 打包_骚操作 | Python 实现在 App 端的人脸识别
- Mac下使用Docker快速搭建pinpont追踪系统APM
- vs2008 sp1安装时候系统盘空间不够问题,解决方式
- HBuilderX日常踩坑之隐私合规检测
- 2010最新***工具包
- 入驻shopee平台后,选择哪一个站点作为首站?
- 让Win7系统屏幕来个大翻转
- iPad商标之争对开发者的影响
- [Unity插件]着色器关键字分析工具ShaderControl
- uni-app 支付宝小程序授权,获取用户基础信息(头像图片地址、昵称、性别、国家码、省份、所在市区)
- VDI虚拟云桌面 和 共享云桌面 区别
- 如何有效管理自己电脑里的文件
- python从国内源下载安装包