设计模式之原型模式

定义

1
2
3
4
5
6
7
原型模式(Prototype): 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
拷贝又分深拷贝和浅拷贝:
浅拷贝:被复制对象的所有变量都含有与原来相同的值,而所有对象的引用都仍然指向原来的对象。
说人话就是:事实上只是copy了一个原来对象的引用
深拷贝:把引用对象的变量指向复制过来的新对象,而不是原有的被引用的对象
说人话就是:就是类似于new了一个对象

代码解释

1
2
3
4
5
6
7
8
9
10
CoverLetter 接口定义了克隆方法和其他必要的操作。
BasicCoverLetter 类实现了 CoverLetter 接口,提供了一个基本的求职信模板。
CoverLetterPrototypeManager 类管理不同类型的求职信原型。
在客户端代码中,我们使用原型管理器创建求职信,然后自定义每封信的内容。

这种方法的优点是:

我们可以轻松创建多个相似但略有不同的求职信。
如果需要添加新类型的求职信,只需在原型管理器中注册新的原型即可。
它提供了一种灵活的方式来创建对象,而无需指定它们的确切类。

代码

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    package Prototype;

import java.util.ArrayList;
import java.util.List;

// 求职信接口
interface CoverLetter extends Cloneable {
CoverLetter shallowCopy();

CoverLetter deepCopy();

void customize(String companyName, String position);

String getContent();

List<String> getSkills();

void addSkill(String skill);
}

// 求职实体类
class BasicCoverLetter implements CoverLetter {
private String template;
private String companyName;
private String position;
private List<String> skills;

public BasicCoverLetter() {
template = "我申请{COMPANY}的{POSITION}职位。" + "技能包括:{SKILLS}" + "期待为{COMPANY}做出贡献。";
skills = new ArrayList<>();
}

@Override
public CoverLetter shallowCopy() {
try {
return (CoverLetter) super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}

@Override
public CoverLetter deepCopy() {
BasicCoverLetter copy = new BasicCoverLetter();
copy.template = this.template;
copy.companyName = this.companyName;
copy.position = this.position;
copy.skills = new ArrayList<>(this.skills);
return copy;
}

@Override
public void customize(String companyName, String position) {
this.companyName = companyName;
this.position = position;
}

@Override
public String getContent() {
String skillsString = String.join(", ", skills);
return template.replace("{COMPANY}", companyName).replace("{POSITION}", position).replace("{SKILLS}", skillsString);
}

@Override
public List<String> getSkills() {
return skills;
}

@Override
public void addSkill(String skill) {
skills.add(skill);
}
}

// 求职资源管理器
class CoverLetterPrototypeManager {
private final BasicCoverLetter prototype;

public CoverLetterPrototypeManager() {
prototype = new BasicCoverLetter();
prototype.addSkill("Java编程");
prototype.addSkill("问题解决");
}

public CoverLetter getShallowCopy() {
return prototype.shallowCopy();
}

public CoverLetter getDeepCopy() {
return prototype.deepCopy();
}
}

// 客户端代码
public class CoverLetterClient {
public static void main(String[] args) {
CoverLetterPrototypeManager manager = new CoverLetterPrototypeManager();

// 浅拷贝
CoverLetter shallowCopy1 = manager.getShallowCopy();
shallowCopy1.customize("谷歌", "软件工程师");
CoverLetter shallowCopy2 = manager.getShallowCopy();
shallowCopy2.customize("微软", "产品经理");

shallowCopy1.addSkill("机器学习");

System.out.println("浅拷贝 1:\n" + shallowCopy1.getContent());
System.out.println("\n浅拷贝 2:\n" + shallowCopy2.getContent());

// 深拷贝
CoverLetter deepCopy1 = manager.getDeepCopy();
deepCopy1.customize("苹果", "iOS开发者");
CoverLetter deepCopy2 = manager.getDeepCopy();
deepCopy2.customize("亚马逊", "云架构师");

deepCopy1.addSkill("Swift编程");

System.out.println("\n深拷贝 1:\n" + deepCopy1.getContent());
System.out.println("\n深拷贝 2:\n" + deepCopy2.getContent());
}
}