设计模式_4_原型模式(对象的拷贝)

原形模式(PrototypePattern, 创建型模式,创建重复对象且保证性能, 对象的克隆)

通常使用原型模式创建一个原型接口, 用于获取创建对象的克隆, 对于浅拷贝与深拷贝不用纠结, 他们二者的区别就在于重写Clonable的clone方法

浅拷贝与深拷贝

浅拷贝: 直接调用Object的clone

public Object clone() {Object clone=null;try {clone=super.clone(); //不用管Object内部元素的情况直接调用Object的clone方法}catch(CloneNotSupportedException e) {e.printStackTrace();}return clone;}

深拷贝: 对clone对象( 此对象内部具有数组/集合/map等复合数据 )内部的数据再进行一次克隆

此处假设clone对象内部有一个ArrayList数组, ArrayList中存储A对象public Object clone() {Object clone=null;try {clone=super.clone();clone.getArray() = new ArrayList<A>(array.size()); //先将内部的ArrayList克隆出来for (int i=0; i < array.size(); i++){// 然后对ArrayList中的数据进行逐一克隆//从数组中获取每个元素, 然后进行克隆, 此处A对象内部没有复合数据, 最后将clone好的数据存入clone的array中clone.getArray().add( (A)array.get(i).clone() );}}catch(CloneNotSupportedException e) {e.printStackTrace();}return clone;}
因为只是调用Object的clone无法对克隆对象内部的数组类型进行复制, 所以还要针对拷贝对象的内部的数组再一次

操作流程

  • 使用方式
	原型模式通过拷贝一个现有对象生成新对象.浅拷贝实现Clonable接口, 重写clone方.深拷贝与浅拷贝一致, 也可以通过实现Serializable读取二进制流1.利用序列化产生的对象是对原对象的复制2.将对象序列化存入缓冲区, 然后将缓冲区对象读出, 用clone的引用指向该对象
  • 角色定义
原型角色:定义用于复制现有的实例来生成新的实例的方法(实现Cloneable接口的类)
具体原型角色:实现用于复制现有实例来生成新实例的方法(具有clone()方法的类)
使用者角色:维护一个注册表, 提供获取clone的类
  • 使用场景
1.资源优化, 类加载需要消耗很多资源, 性能和安全要求高的场景
2.通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模型
3.一个对象,多个修改者
4.大多数原型模式伴随工厂模式出现,通过clone方法创建一个对象,然后由工厂方法提供给调用者
  • 优点
    性能提高,逃避构造函数的约束, 不推荐使用序列化处理clone

  • 缺点
    配备克隆操作需要对类的功能全盘考虑,对已有的类不一定很容易,特别是当一个类饮用不支持串行化的间接对象,或者引用含有循环结构(对象出现多层次的引用); 必须实现Cloneable接口

代码演示:

利用克隆, 事先将一些构造需要高代价的对象放入缓冲区, 然后在下次需要新的对象的时候直接去缓冲区拿( 缓冲区利用clone的方式给新对象, 而不是通过构造函数 )

package com.PrototypePattern;import java.util.Hashtable;public class ShapePrototypePattern {public static void main(String[] args) {//设计一个圆形的缓冲区Shape shape = new Circle();shape.setId("1");ShapeCache.loadCache(shape);//使用对应的图形缓冲区获得克隆对象clone, clone1, clone2Shape clonedShape=ShapeCache.getShape("1");System.out.println("Shape: "+clonedShape.hashCode());Shape clonedShape1=ShapeCache.getShape("1");System.out.println("Shape: "+clonedShape1.hashCode());Shape clonedShape2=ShapeCache.getShape("1");System.out.println("Shape: "+clonedShape2.hashCode());}}
//针对不同的图形设计不同的缓冲区模块克隆模块
class ShapeCache{private static Hashtable<String,Shape>shapeMap=new Hashtable<String,Shape>();//使用get方法获得的图形都是原图形的克隆对象public static Shape getShape(String id) {Shape cachedShape=shapeMap.get(id);return (Shape)cachedShape.clone();}//将new出的对象放入Hashtable, 获得相应的图形直接获取clonepublic static void loadCache(Shape shape) {shapeMap.put(shape.getId(), shape);}
}//原型角色,实现Cloneable接口,调用Object的clone方法
//当具体实现类需要clone的时候就可以直接调用clone
abstract class Shape implements Cloneable{private String id;protected String type;abstract public void draw(); public String getType() {return type;}public String getId() {return id;}public void setId(String id) {this.id=id;}public Object clone() {Object clone=null;try {clone=super.clone();}catch(CloneNotSupportedException e) {e.printStackTrace();}return clone;}
}class Circle extends Shape{public Circle() {type="Circle";}@Overridepublic void draw() {System.out.println("Circle");}
}
class Rectangle extends Shape{public Rectangle() {type="Rectangle";}@Overridepublic void draw() {System.out.println("Rectangle");}
}
class Square extends Shape{public Square() {type="Square";}@Overridepublic void draw() {System.out.println("Square");}
}

结语:

原型模式就是clone, 用于提高性能, 避免构造对象的时候加大资源的开销

上面有错, 还请指出, 如果认为我写的还不错, 还请点个赞, 多多支持一下, O(∩_∩)O~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/468694.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vk_down 每次下翻丙行 c++_笔记本接口不够用?不妨试试这款Type-C拓展坞,给你7个接口用...

随着笔记本电脑越来越轻薄化&#xff0c;已经很难再布局较多的数据接口了&#xff0c;但是在办公等环境下总是需要这些接口来满足需求。就拿小新个人来说&#xff0c;使用的是小米笔记本12.5寸款的&#xff0c;该款笔记本仅有三个接口&#xff0c;分别是全功能 USB-C 接口 x 1、…

学习,才是最好的投资~

推荐语&#xff1a;我因为王小波常说而喜欢的英国哲学家罗素的一句话&#xff1a; 参差多态乃是幸福的本源。正是因为有了多种多样的行业&#xff0c;才使得我们的职业也是多种多样&#xff0c;行行出大牛&#xff01;这个世界天生就注定有人搞互联网的&#xff0c;Linux&#…

第二百四十八节,Bootstrap轮播插件

Bootstrap轮播插件 学习要点&#xff1a; 1.轮播插件 本节课我们主要学习一下 Bootstrap 中的轮播插件。 一&#xff0e;轮播 轮播插件就是将几张同等大小的大图&#xff0c;按照顺序依次播放。 基本实例。 第一步&#xff0c;给轮播器区域div设置一个id给轮播器区域div设置样…

设计模式_4_适配器模式(AdapterPattern, 多个功能的结合)

适配器模式(AdapterPattern, 结构型模式) 用最通俗的讲法就是: 将多个功能相关或不相关的接口( 你需要的接口 )放到同一个实现类里, 构造一个具有多工功能, 多特点的"异类对象" 定义 是作为多个接口之间的桥梁,结合多个独立的接口(将多个类/功能结合在一起,构建出一…

xgboost分类_XGBoost(Extreme Gradient Boosting)

一、XGBoost在Ensemble Learning中的位置机器学习中&#xff0c;有一类算法叫集成学习&#xff08;Ensemble Learning&#xff09;&#xff0c;所谓集成学习&#xff0c;指将多个分类器的预测结果集成起来&#xff0c;作为最终预测结果&#xff0c;它要求每个分类器具备一定的“…

Android技术架构演进与未来

本文阅读大约需15分钟 引言众所周知&#xff0c;Android是谷歌开发的一款基于Linux的开源操作系统&#xff0c;每年迭代一次大版本升级。 小米、华为、OPPO、VIVO、三星等各大厂商对Android原生系统进行二次开发衍生出具有各家特色的系统&#xff08;比如MIUI&#xff09;&…

Sublime Text 3插件安装方法

一&#xff1a;安装Sublime Text 3插件的方法安装package control组件&#xff0c;然后直接在线安装&#xff1a;1、按Ctrl调出console&#xff08;注&#xff1a;安装有QQ输入法的这个快捷键会有冲突的。输入法属性设置-输入法管理-取消热键切换至QQ拼音&#xff09; 2、粘贴下…

Hibernate_1_配置文件详解_基础案例_Hibernate工具类_API详解_持久化类编写规则

Hibernate( ORM框架 ) Hibernate是一个数据持久化层的ORM框架. 它通过JavaBean, 数据库中的表与自身的映射关系达到表中数据的增删改查 特性 1.对JDBC访问数据库的代码进行封装, 简化数据访问的重复性代码 2.使用反射机制完成对Bean的封装 3.轻量级框架,支持关系型数据库 核…

建筑电气工程设计常用图形和文字符号_建筑水电图纸看不懂?10年老师傅教你看图技巧,分分钟安排...

1、建筑给排水工程包括&#xff1a;给水、排水、热水、消火栓、自动喷淋等常用系统&#xff0c;其管道当中流动的是水。(其管道输送介质为水)2、给排水系统的主要功能&#xff1a;(1)建筑给水系统的任务&#xff0c;就是经济合理地将水由室外给水管网输送到装置在室内的各种配水…

Android系统架构开篇

Android系统庞大且错综复杂&#xff0c;Gityuan带领大家初探Android系统整体架构&#xff0c;一窥其全貌。一、引言本文作为Android系统架构的开篇&#xff0c;起到提纲挈领的作用&#xff0c;从系统整体架构角度概要讲解Android系统的核心技术点&#xff0c;带领大家初探Andro…

20155220 实验三 敏捷开发与XP实践 实验报告

20155220 实验三 敏捷开发与XP实践 实验报告 实验内容 XP基础XP核心实践相关工具实验要求 没有Linux基础的同学建议先学习《Linux基础入门&#xff08;新版&#xff09;》《Vim编辑器》 课程完成实验、撰写实验报告&#xff0c;实验报告以博客方式发表在博客园&#xff0c;注意…

Hibernate_2_Hibernate中对象状态及转化_一级缓存_Session详解_HQL/SQL/Criteria_一对多关系_级联操作

Hibernate中的对象状态 在Hibernate中持久化对象具有三种状态: 瞬时态, 持久态, 游离态. 瞬时态: 对象没有与Hibernate产生关联(transient,session中没有缓存), 数据库中也没有对应记录> 对象无id, 没有关联 持久态: 对象与Hibernate产生关联(persistent, session中有缓存…

python正则表达式操作指南_第二篇详细Python正则表达式操作指南(re使用)

接下来昨天的内容执行匹配一旦你有了已经编译了的正则表达式的对象&#xff0c;你要用它做什么呢&#xff1f;RegexObject 实例有一些方法和属性。这里只显示了最重要的几个&#xff0c;如果要看完整的列表请查阅 Python Library Reference如果没有匹配到的话&#xff0c;match…

Android binder 框架和学习资料

&#xff11;Android binder 是学习 Android 系统一定要啃得硬骨头&#xff0c;可能你刚开始的时候并不理解其中的精髓&#xff0c;但是在 android 系统的很多地方你都会遇到它。不过要我自己写明白其中的逻辑脉络需要花费太多的时间和精力&#xff0c;而且传播效果也不是非常好…

Spring_Bean配置_生命周期_注解

Spring Spring是一个开源框架&#xff0c;Spring是于2003 年兴起的一个轻量级的Java 开发框架&#xff0c;由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之…

完全理解Gson(1):简单入门

GSON是Google开发的Java API&#xff0c;用于转换Java对象和Json对象。本文讨论并提供了使用API的简单代码示例。更多关于GSON的API可以访问&#xff1a;http://sites.google.com/site/gson/. 本文是GSON系列文章的第一篇。本文是其他文章的基础&#xff0c;因此不需要任何GSON…

python自由落体_VPython - example - 模拟自由落体运动

作者&#xff1a;liuyuan_jq2011-04-10from visual import *scene.width 400scene.height 300scene.autoscale 0scene.range (100,100,100)scene.center (0,40,0)ball sphere(pos(0,100,0),radius2)ground box(pos(0,-1,0),size(10,2,10))gravity 9.8 # m/s**2seconds …

创业碎碎念

&#xff11;今天&#xff0c;跟几条跟我玩的比较好的篮球狗在讨论人生&#xff0c;其中有一条特别感慨&#xff0c;「为何看上去别人做起来这么容易的事&#xff0c;我们做很难&#xff1f;」。我突然不知道如何去回答这样的问题&#xff1f;这个问题也一直困扰着我。读我文章…

压缩过的js代码怎么还原_Fundebug 前端 JS插件更新至 1.7.0,拆分录屏代码,还原部分 Script error....

摘要&#xff1a; BUG 监控插件压缩至 18K。1.7.0拆分了录屏代码&#xff0c;BUG 监控插件压缩至18K&#xff0c;另外我们还原了部分 Script error&#xff0c;帮助用户更方便地 Debug。请大家及时更新哈~拆分录屏代码从1.7.0版本开始&#xff0c;我们拆分了录屏代码。如果需要…

SpringAOP描述及实现_AspectJ详解_基于注解的AOP实现_SpringJdbcTemplate详解

AOP AOP特点: 面向切面编程, 利用AOP对业务逻辑的各个部分进行抽取公共代码, 降低耦合度, 提高代码重用性, 同时提高开发效率.采取横向抽取, 取代传统纵向继承体系重复性代码解决事务管理, 性能监视, 安全检查, 缓存, 日志等问题Spring AOP在运行期, 通过反向代理的方式解决类…