设计模式(六)原型模式

假设我们需要复制一个对象,在JAVA中通常做法有两种,浅克隆(ShallowClone)和深克隆(DeepClone)。

浅克隆:

####

深克隆:

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package info.aviraer.design_pattern.create.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Student implements Cloneable, Serializable{

private static final long serialVersionUID = 1L;

private String name;

private Integer age;

private StudentDetail detail;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public StudentDetail getDetail() {
return detail;
}

public void setDetail(StudentDetail detail) {
this.detail = detail;
}

protected Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}

protected Student deepClone() throws IOException, ClassNotFoundException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(baos);
out.writeObject(this);
out.flush();
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
return (Student) in.readObject();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package info.aviraer.design_pattern.create.prototype;

import java.io.Serializable;

public class StudentDetail implements Serializable{

private static final long serialVersionUID = 5164689179149057541L;

private String address;

private String phone;

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package info.aviraer.design_pattern.create.prototype;

import java.io.IOException;

public class Main {

public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
Student s1 = new Student();
s1.setName("Jack");
s1.setAge(30);
StudentDetail detail = new StudentDetail();
detail.setAddress("address");
detail.setPhone("phone");
s1.setDetail(detail);

//浅克隆
Student s2 = s1.clone();
s1.setAge(15);
System.out.println(s2.getAge());
System.out.println(s2.getDetail().getPhone());
System.out.println(s1.getDetail() == s2.getDetail());
System.out.println("=========================================");

//深克隆
Student s3 = s1.deepClone();
System.out.println(s3.getDetail().getPhone());
System.out.println(s1.getDetail() == s3.getDetail());
}

}

模式分析:

优势:

1.通过clone创建复杂对象可以有效简化创建过程。

2.可辅助实现撤销操作。(将操作对象复制一份,撤销时还原该对象)。

 

劣势:

1.对类进行修改时clone方法也需要调整,违反开闭原则。

2.多个类嵌套深克隆时所有类都需要支持深克隆。

 

适用场景:

1.创建对象消耗资源较大。