版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_28196435/article/details/86760485
原型模式
原型模式是一个比较简单的创建模式,在java中当需要创建大量对象的时候,为了提升效率和性能,我们可以使用原型模式
原型模式一般和工厂模式配合使用,用来创建对象
下面介绍java的原型模式实现过程
Java的Object
类中具有clone
方法,这表示任何对象都可以实现克隆,如下所示
package com.natsuki;
import java.util.Date;
/**
* @author natsuki
* created at 2018-11-29
*/
public class WeeklyLog implements Cloneable {
private String name;
private String date;
private String content;
private Date birthday;
private Attachment attachment;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Attachment getAttachment() {
return attachment;
}
public void setAttachment(Attachment attachment) {
this.attachment = attachment;
}
@Override
public WeeklyLog clone(){
WeeklyLog weeklyLog = null;
try {
weeklyLog = (WeeklyLog) super.clone();
weeklyLog.attachment = attachment.clone();
weeklyLog.birthday = (Date) birthday.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return weeklyLog;
}
@Override
public String toString() {
return "WeeklyLog{" +
"name='" + name + '\'' +
", date='" + date + '\'' +
", content='" + content + '\'' +
", birthday=" + birthday +
", attachment=" + attachment +
'}';
}
}
package com.natsuki;
import java.text.MessageFormat;
/**
* @author natsuki
* created at 2018-11-29
*/
public class Attachment implements Cloneable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void download(){
System.out.println(MessageFormat.format("下载附件,文件名为:{0}",this.name));
}
@Override
public Attachment clone() {
Attachment attachment = null;
try {
attachment = (Attachment) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return attachment;
}
}
这里需要注意两点,首先需要继承Cloneable标志接口,然后重写clone方法,注意这里由于Date类型的属性和Attachment类型的属性都是对象属性,在默认的clone方法中只能进行浅拷贝,即拷贝的是对象地址,所以为了进行深拷贝需要重写编写clone方法。将对象类型进行手动拷贝。
当然我们还可以使用序列化和反序列化的方式实现深拷贝
js中也有深浅拷贝的概念,比如Object.assign
默认的就是浅拷贝,另外我们还可以通过展开运算符 ...
来实现浅拷贝。
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = { ...a }
a.jobs.first = 'native'
console.log(b.jobs.first) // native
第二个例子就说明了浅拷贝,实际上a和b中的jobs还是同一个对象。
大部分浅拷贝是足够应付业务的,但是如果要实现深拷贝的话,通常可以使用JSON.parse(JSON.stringify(object))
来解决
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
但是这个方法有个明显的坑,就是不能序列化函数。。在带有函数的对象中就无能为力了。
let a = {
age: undefined,
sex: Symbol('male'),
jobs: function() {},
name: 'yck'
}
let b = JSON.parse(JSON.stringify(a))
console.log(b) // {name: "yck"}
包括Symbol和undefined类型,也不能序列化
如果序列化不能满足需求的话,这里推荐使用lodash
的工具函数进行深拷贝