android设计模式-原型设计(深、浅拷贝)

转https://www.jianshu.com/p/15bc149bd0af

前言

使用原形模式可以解决复杂对象构建资源消耗的问题

原形模式是一种创建型模式,原形模式多用于创建复杂对象或者构造耗时的实例。它的作用主要是"克隆",用户从原形对象复制出一个内部属性一样的对象。因为类的初始化需要耗费很多的资源,原形拷贝则可以更高效。

原形模式

由原形实例指定创建对象的种类,并通过拷贝这些原形创建新的对象

原形模式举例

继承Cloneable然后必须用Object clone。把需要clone的东西属性放进去。

浅拷贝支持对象:(8种基本数据类型byte,char,short,int,long,float,double,boolean)、

其他的都需要深拷贝:数组、对象等、string

浅拷贝如果用了8种数据之外的,会有影响到原始的对象。所有要进行深拷贝。

浅拷贝理解成获取到的是变量的本身,所以调用的时候直接得到的值就是原对象的数据

深拷贝理解成得到了一个一模一样的权限变量,可以对其赋值等等,不会影响到原对象。

深拷贝就需要对深拷贝的对象加上clone.也可以理解成拷贝两次吧。就是person已经在前面的clone了一次,再调用一次clone

person.books = (ArrayList<String>) this.books.clone();

import android.util.Log;import java.util.ArrayList;public class Person implements Cloneable{private String name;private int age;private ArrayList<String> books = new ArrayList<String>();public Person() {}@Overridepublic Object clone() {Person person = null;try {person = (Person) super.clone(); //super.clone()理解成一组person.age = this.age;person.name = this.name;person.books = this.books;return  person;} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}public void setAge(int age) {this.age = age;}public int getAge() {return age;}public void setName(String name) {this.name = name;}public String getName() {return name;}public ArrayList<String> getBooks() {return books;}public void addBook(String bookName) {books.add(bookName);}public void printPerson() {Log.d("prototype","age = " + age);Log.d("prototype","name = " + name);if (books.size() > 0 ) {for (String bookName:books) {Log.d("prototype","book name = " + bookName);}}}
}

1、Person类继承implements Cloneable接口,Cloneable标示接口,表示这个对象可以被拷贝。
2、clone方法是Object中的方法,如果实现clone方法没有继承Cloneable会抛出异常
看看如何调用:

        Person xiaoMing =  new Person();xiaoMing.addBook("a");xiaoMing.addBook("b");xiaoMing.setAge(18);xiaoMing.setName("xiaoMing");Person xiaoHong = (Person) xiaoMing.clone();xiaoHong.setName("xiaoHong");xiaoHong.addBook("c");xiaoHong.printPerson();xiaoMing.printPerson();

输出如下:

    age = 18name = xiaoHongbook name = abook name = bbook name = cage = 18name = xiaoMingbook name = abook name = bbook name = c

1、对象xiaoHong由xiaoMing克隆生成。
2、调用clone方法克隆一个对象时不会走其构造方法。

浅拷贝、深拷贝

我们可以看到private ArrayList<String> books输出都一样,说明xiaoHong和xiaoMing这两个实例对象的参数是相同的。他们指向同一个引用地址。这种拷贝就叫做浅拷贝。通常我们想在clone的时候不想印象原本的对象xiaoMing,因为我们不想改变xiaoHong的时候还会改变xiaoMing,这时候,我们就应该深拷贝。
深拷贝应该这样:

@Overridepublic Object clone() {Person person = null;try {person = (Person) super.clone();person.age = this.age;person.name = this.name;person.books = (ArrayList<String>) this.books.clone();return  person;} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}

我们再看下这个时候的输出

    age = 18name = xiaoHongbook name = abook name = bbook name = cage = 18name = xiaoMingbook name = abook name = b

这个时候books输出就正确了,这个时候我们思考这样一个问题,age和name为啥不会影响,而只有books是浅拷贝呢。
其实这个更好理解了,因为int和String一个是整形一个是字符串,都是值类型而不是引用类型,因此他们不需要clone,在副本对象克隆好之后,直接返回给客户端对象即可。

深拷贝的只读保护

深拷贝还有一个用处就是只读。当我们想保护某一个实例不被随意更改的时候,通常我们把set方法设为私有。我们先看这样写

public class Master {private static Master master;private Person mPerson;private Master() {}public static Master getMaster () {if (master == null) {master = new Master();}return master;}protected  void setPerson(Person person) {this.mPerson = person;}public Person getPerson() {return mPerson;}
}

1、我们创建了一个Master,Master是单例,拥有一个Person类,我们视为一个主人。
2、设置这个主人的方法我们定义为protected,包安全,即在同一个包名下的类才可以修改。唯一修改主人的途径。
在使用的时候发现没能真正的保护起来,当我想在其他包名下调用时确实不能调用

 Master master = Master.getMaster();//master.setPerson(xiaoMing);   不能调用会提示方法protected

但是我们却可以这样来改

Master master = Master.getMaster();
master.getPerson().setName("jack");

这样肯定不行的,因为我们的目的是只能通过包级私方法去设置修改,那么我们应该这样做

public Person getPerson() {return (Person)mPerson.clone();}

至此,我们返回的是clone的一个对象,你拿到这个对象无论怎么修改,都不会影响Master真正的主人

总结

最后,原形模式其实就是对象的拷贝,这跟C++/Object-C中的clone类似,容易出问题的也就在深浅拷贝上,使用原形模式可以解决复杂对象构建资源消耗的问题。也可以用来只读保护。注意其clone时不会走构造函数。



作者:Yink_Liu
链接:https://www.jianshu.com/p/15bc149bd0af
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

相关文章

Kafka-ACK机制(ack应答原理、冥等性、事务)

Kafka-ACK机制 Kafka中的ACK&#xff08;Acknowledgement&#xff09;机制是用于保证消息可靠传递的关键组件之一。在生产者发送消息到Kafka集群时&#xff0c;ACK机制决定了何时认为消息已经成功发送。这个机制非常重要&#xff0c;因为它影响了生产者对消息发送的信心以及消费…

【MySQL】两个脚本自动化搞定 MySQL 备份恢复--XtraBackup

简介 此项目基于两个脚本实现&#xff0c;pxb_auto_backup.sh 脚本基于 XtraBackup 实现了 MySQL 的自动化备份&#xff0c;可选择全备和增备。pxb_auto_recovery.sh 脚本实现了基于 pxb_auto_backup.sh 脚本的自动化恢复&#xff0c;并能够通过微信和企业微信对执行的状态进行…

k8s使用Volcano调度gpu

k8s部署 https://www.yangxingzhen.com/9817.html cri-dockerd安装 https://zhuanlan.zhihu.com/p/632861515 安装nvidia-container-runtime https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html 安装k8s-device-plugin https://…

降本增效!看TeeChart如何帮助实现海量「监测数据」可视化

“环境监测数据异常庞大&#xff0c;想要实现数据监测分析&#xff0c;除了要求控件具有良好的兼容性和稳定性&#xff0c;还对多样化、定制化的图表开发也有很高的要求” ——————— 项目负责工程师 王工 TeeChart Pro 最新版下载&#xff08;qun&#xff1a;740060302&…

Transformer系列专题(二)——multi-headed多头注意力机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、什么是multi-headed&#xff08;多头注意力机制&#xff09;二、multi-headed三、multi-headed结果四、堆叠多层总结 前言 在实践中&#xff0c;当给定相同…

Redis常见数据类型(3)-String, Hash

目录 String 命令小结 内部编码 典型的使用场景 缓存功能 计数功能 共享会话 手机验证码 Hash 哈希 命令 hset hget hexists hdel hkeys hvals hgetall hmget hlen hsetnx hincrby hincrbyfloat String 上一篇中介绍了了String里的基本命令, 接下来总结一…

git submodule的使用

一、添加submodule 克隆子项目到当前项目目录下 git submodule add https://github.com/maonx/vimwiki-assets.git submodule_filename 如果是希望克隆到项目下的指令路径&#xff0c; git submodule add -b <branch> <remote> <path> 不指定分支就不传…

Json生成Excel,预览Excel(前端)

前端生成Excel&#xff0c;预览Excel 一、xlsx sheetJs 中文文档 npm i xlsx1、代码详情 <template><div><input type"file" id"fileInput" change"uploadChange" /><div v-html"vHtml"></div><…

深入了解Java中的BigDecimal类及其方法

在Java中&#xff0c;BigDecimal类是一个用于精确计算浮点数的不可变类&#xff0c;特别适用于财务计算&#xff0c;能够避免传统浮点类型可能导致的精度问题。本文将详细介绍BigDecimal类及其常用方法&#xff0c;并通过示例说明如何使用这些方法。 基本介绍 BigDecimal类允…

AJAX、

文章目录 AJAX1. AJAX简介AJAX特点 2. XML简介3. AJAX发送get请求4. post请求设置体参数5. 设置请求头信息6. AJAX请求服务端响应json数据7. ie缓存问题8. 请求超时问题和网络异常9. 取消请求10. 请求重复取消11. jQuery中的AJAX请求12. axios函数发送AJAX使用fetch函数发送AJA…

跨境电商赛道,云手机到底能不能化繁为简?

当下国内电商背景&#xff1a; 从零售额的数据来看&#xff1a;随着互联网的普及和消费者购物习惯的改变&#xff0c;国内电商市场规模持续扩大。据相关数据显示&#xff0c;网络消费亮点纷呈&#xff0c;一季度全国网上零售额达到了3.3万亿元&#xff0c;同比增长12.4%。这表…

html 段落与排版标记 Web前端开发技术、详细文章(例如)

段落与排版标记 网页的外观是否美观&#xff0c;很大程度上取决于其排版。在页面中出现大段的文字&#xff0c;通常采用分段进行规划&#xff0c;对换行也有极其严格的划分。本节从段落的细节设置入手&#xff0c;利用段落与排版标记自如地处理大段的文字。 段落p标记 在HTM…

探索SRM系统的未来:第一批吃螃蟹的企业如何用API/插件打破效率瓶颈?

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 一、SRM开放集成实践前瞻 二、开放集成渐成系统升级新趋势 降本增效是企业经营的一大永恒话题。通常而言&#xff0c;企业在不同发展阶段中&#xff0c;会使用到不同的管理系统&#xff0c;或产生不同的业务场…

react 使用 Reducer 和 Context 进行纵向扩展

Reducer 允许您合并组件的状态更新逻辑。上下文允许您将信息深入传递到其他组件。您可以将 reducer 和 context 组合在一起&#xff0c;以管理复杂屏幕的状态。 将减速器与上下文相结合 在 reducer 简介中的此示例中&#xff0c;状态由 reducer 管理。reducer 函数包含所有状…

LLM提示词编写技巧-prompt必知必会

LLM大模型提示词编写技巧 提示词的构成要素基础技巧添加明确的语法分解任务指定输出结构 进阶技巧少样本学习 Few Shot零样本学习zero shot思维链提示 CoTCO-STAR框架 高阶技巧自动推理并生成工具 ART推理行动 ReACT 好用的提示词示例绘制工作流程图编写技术博客 参考资料 提示…

热红外传感器

热红外传感器 一、热红外测温原理二、热红外传感器三、MLX90640-D55(MLX90640-BAB)测试 一、热红外测温原理 自然界中当物体的温度高于 绝对零度 时&#xff0c;由于它内部 热运动 的存在,就会不断地向四周辐射电磁波&#xff0c;其中就包含了波段位于0.75&#xff5e;100μm …

K8S认证|CKA题库+答案| 14. 排查故障节点

14、排查集群中的故障节点 您必须在以下Cluster/Node上完成此考题&#xff1a; Cluster Master node Worker node wk8s master …

Java核心面试基础

1.1核心知识 1.1.1 数据类型 Java中的数据类型可以分为两大类&#xff1a;基本数据类型&#xff08;Primitive Data Types&#xff09;和引用数据类型&#xff08;Reference Data Types&#xff09; 基本数据类型 基本数据类型是Java语言中内置的、不可再分的数据类型。Java…

LLMjacking:针对云托管AI大模型服务的新型攻击

Sysdig威胁研究团队(TRT)观察到一种新型攻击&#xff0c;命名为LLMjacking。它利用窃取的云凭证&#xff0c;对托管在云上的十个大型语言模型(LLM)服务发起攻击。 这些凭证是从一个流行的目标获得&#xff0c;即运行着一个存在漏洞的Laravel版本&#xff08;CVE-2021-3129&…

常见算法(1)

1.基本查找/顺序查找 核心&#xff1a;从0索引之后挨个查找 实现代码&#xff1a; public class test {public static void main(String [] arg) throws ParseException {int[] arr {121,85,46,15,55,77,63,49};int number55;System.out.println(bashi(arr,number));}publi…