当前位置: 首页 > news >正文

网站建设服务器百度云灰色行业seo大神

网站建设服务器百度云,灰色行业seo大神,招标网站哪个好,面试网站建设问题文章目录 1.原型模式概述2.浅拷贝与深拷贝2.1.浅拷贝的实现方式2.2.深拷贝的实现方式 3.结语 1.原型模式概述 原型模式是一种非常简单易懂的模型,在书上的定义是这样的: Specify the kinds of objects to create using a prototypical instance,and cre…

文章目录

  • 1.原型模式概述
  • 2.浅拷贝与深拷贝
    • 2.1.浅拷贝的实现方式
    • 2.2.深拷贝的实现方式
  • 3.结语

1.原型模式概述

原型模式是一种非常简单易懂的模型,在书上的定义是这样的:

Specify the kinds of objects to create using a prototypical instance,and create new objects by
copying this prototype.
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

通俗的讲,就是有一个现成的对象,我们通过复制或拷贝这个对象的方式来创建一个新的对象,这就是原型模式。


那么,我们为什么需要通过拷贝来创建对象呢?
我认为主要体现在两个维度:程序运行效率开发效率

  • 程序运行效率:如果对象的创建和初始化的代价比较大,创建比较繁琐,例如需要从数据库、RPC、网络等获取一些数据才能完成创建,这时候使用原型模式拷贝出一个对象无疑是效率更高的做法。
  • 开发效率:我们在业务开发中,会涉及到不同的分层,每个分层都有自己的数据实例,例如与前端交互的VO对象,数据传输的DTO对象,与数据库交互的PO对象等等,这些对象转换的过程中大部分的字段值都是相同的,如果每一层都使用getter/setter方法来进行赋值,开发效率就很容易受到影响,尤其是在迭代中增加了新字段的情况下,每一层都需要新增一个字段set方法,很麻烦也很容易做漏,这时候使用原型模式来进行复制就比较方便了。

严格的说,原型模式是同一个类型下的不同实例的数据拷贝,对于不同类型的实例拷贝更应该归类于原型模式的一种拓展用法。不过在业务中,这种拓展用法使用的频率更高,接下来的示例也是以这种拓展用法为主。

2.浅拷贝与深拷贝

想要在使用原型模式的时候,不出现一些“意外”,那就得先了解浅拷贝与深拷贝之间的区别

两者的区分非常好理解,关键点就是在对引用类型的成员变量拷贝上,两种拷贝类型有不同的结果:

  • 浅拷贝:只会将原始对象中的引用类型变量的内存地址复制给目标对象的同名成员变量。
  • 深拷贝:会以引用类型变量的类型为基础,创建一个崭新的对象,再把这个新对象的内存地址赋值给目标对象的对应同名成员变量。

对于浅拷贝来说,如果原始对象中有其他的引用类型变量,在拷贝出目标对象后,两个对象对于该引用类型变量的修改会互相影响,但是由于不需要针对引用类型的变量查询新的对象,这种拷贝方式的效率较高。在不会修改变量值或者只需要修改基本类型的变量值(包含String)时,优先考虑使用浅拷贝。

如果拷贝的对象中包含了引用类型的对象,且需要进行修改,或者拷贝不同类型但内部字段相同的对象(例如:UserPO和UserDTO),可以考虑使用深拷贝。

2.1.浅拷贝的实现方式

浅拷贝的实现方式有很多,归类起来主要是两种,一种是使用Java原生的方式,另一种是通过开源的工具包实现。


先看看Java原生的方式,实现一个Cloneable接口,并覆写父类Object中的clone方法:

@Getter
@Setter
public class User implements Cloneable {private String name;private int age;private Phone phone;@Overridepublic User clone() throws CloneNotSupportedException {return (User) super.clone();}
}@Getter
@Setter
public class Phone {private String phoneNumber;
}

为了验证浅拷贝,这里还加入了一个Phone对象,接下来就做个测试。

public static void main(String[] args) throws CloneNotSupportedException {User user = new User();user.setName("张三");user.setAge(18);user.setPhone(new Phone());User cloneUser = user.clone();System.out.println(user.getPhone() == cloneUser.getPhone());
}

打上一个断点,查看两个对象,可以看到User对象已经成功复制,并且里面的Phone对象明显是同一个对象,
在这里插入图片描述


使用开源的工具,常用的有两种工具分别是Apache commons中的BeanUtilsPropertyUtilsSpring中的BeanUtils,他们都有一个共同的方法是copyProperties用来拷贝对象属性。在实现中,虽然ApacheSpring都是通过反射来实现的,但是Spring针对反射做了一层缓存,在相同类型的对象复制中,效率高于Apache,所以我们选择使用Spring的拷贝。

没有Spring依赖的话,需要引入依赖包:

<dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.3.9</version>
</dependency>

修改一下代码,可以得到一样的结果:

public static void main(String[] args) {User user = new User();user.setName("张三");user.setAge(18);user.setPhone(new Phone());User cloneUser = new User();BeanUtils.copyProperties(user, cloneUser);System.out.println(user.getPhone() == cloneUser.getPhone());
}

在这里插入图片描述

2.2.深拷贝的实现方式

深拷贝的实现有两种方式,一种是通过递归来拷贝,既然一次拷贝对于引用变量来说只能拷贝地址,那就再把引用变量也做一次拷贝就可以了,只是这种方式太麻烦了。我们一般会选择第二种方式,通过序列化反序列化来完成对象的拷贝。

其实在我们常见的RPC通信中,就是使用的这种方式来完成对象拷贝的,请求方将对象序列化成流、字节数组、JSON、XML等等方式来做传输,接收方收到数据后,用同样的方式反序列化成一个新的对象。我们也可以采用这种方式来完成对象的拷贝。


这里使用一个FastJson工具类做了一个简单的封装,封装了两个方法,拷贝单个对象和拷贝List对象:

public class DeepCloneUtil {/*** 克隆单个对象** @param source      被克隆的源对象* @param targetClazz 克隆目标对象的类型* @param <T>         目标对象泛型* @return 克隆模板对象*/public static <T> T cloneObject(Object source, Class<T> targetClazz) {String jsonString = JSON.toJSONString(source);return JSON.parseObject(jsonString, targetClazz);}/*** 克隆List对象** @param source      被克隆的源对象* @param targetClazz 克隆目标对象的类型* @param <T>         目标对象泛型* @return 克隆模板对象*/public static <T> List<T> cloneList(List<?> source, Class<T> targetClazz) {String jsonString = JSON.toJSONString(source);return JSON.parseArray(jsonString, targetClazz);}}

修改一下测试代码:

public static void main(String[] args) {User user = new User();user.setName("张三");user.setAge(18);user.setPhone(new Phone());User cloneUser = DeepCloneUtil.cloneObject(user, User.class);System.out.println(user.getPhone() == cloneUser.getPhone());
}

在这里插入图片描述
此时,两个Phone对象就不是同一个对象了,这样就完成了深拷贝。


再试试列表拷贝:

public static void main(String[] args) {User user = new User();user.setName("张三");user.setAge(18);user.setPhone(new Phone());User user1 = new User();user1.setName("李四");user1.setAge(19);user1.setPhone(new Phone());List<User> list = Arrays.asList(user, user1);List<User> cloneList = DeepCloneUtil.cloneList(list, User.class);}

在这里插入图片描述
可以看到不管是List,还是User,还是Phone,每一个都是不同的对象。

3.结语

本篇主要讲述的是原型模式的概念及其使用,并引出了深拷贝与浅拷贝的区别。
不管是从创建对象的性能上考虑,还是从开发效率上考虑,都可以在合适的时候选择使用原型模式拷贝对象的方式来替代从头开始创建一个新的对象。

http://www.mmbaike.com/news/85685.html

相关文章:

  • 做外汇著名网站seo网站推广助理招聘
  • 长沙公司网站建设win7优化教程
  • 做经营性的网站需要注册什么条件站长工具网站
  • 网站权重如何速度增加广州网络营销
  • 西宁做网站_君博优选在线排名优化工具
  • 做网站语言知乎营销网络是什么意思
  • 网站的建设的含义百度竞价登录
  • 自己注册了个域名想做一个网站seo导航
  • 可以做翻译兼职的网站有哪些怎么免费建立网站
  • 重庆网站建设 快速建站网站seo运营培训机构
  • 网站源码换模板北京网络推广公司wyhseo
  • 做海鲜代理在什么网站营销策划方案怎么写?
  • 温州建设网站制作内容营销是什么意思
  • 武汉市人民政府网站网络广告的优势有哪些
  • 广丰做网站公司广州权威发布
  • 班级网站模板宁波网站制作设计
  • 长沙做网站哪个最好济南seo小黑seo
  • 在日本做网站的公司有哪些潍坊网站建设咨询
  • 国内做的比较好的网站是什么代运营电商公司排行榜
  • 个人开网站舆情网站入口
  • 阜宁网站设计企业培训心得
  • 太原网站建设方案报价如何做营销策划方案
  • 网站开发公司成都关键词seo公司
  • 设计网站推荐提升审美百度官网首页官网
  • 五金网站方案软件关键词排名
  • 开发是什么工作win10优化大师好用吗
  • 如何设置网站的关键词百度产品优化排名软件
  • 门户网站建设经验交流seo搜索引擎优化排名
  • 网站内容维护制造企业网站建设
  • 安阳市城乡建设规划局网站关键词热度