先给出一个情景:设计一个简历类

我们需要考虑的

  • 易于修改
  • 尽量减少实例化的次数(提高性能)

原型模式UML图

avatar

原型模式:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象

基于模式原型的代码实现

原型类

1
2
3
4
5
6
7
8
9
public abstract class Prototype implements Cloneable{
private String id;
public Prototype(String id) {
this.id = id;
}

public String getId() { return id; }
public void setId(String id) { this.id = id; }
}

具体原型类

1
2
3
4
5
6
7
8
9
10
public class ConcretePrototype extends Prototype {
public ConcretePrototype(String id) {
super(id);
}

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

客户端

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
ConcretePrototype p1 = new ConcretePrototype("I");
ConcretePrototype c1 = null;
try {
c1 = (ConcretePrototype)p1.clone();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(c1.getId());
}

基于情景的代码实现

简历类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Resume implements Cloneable {
String name;
String sex;
public Resume(String name, String sex) {
this.name = name;
this.sex = sex;
}

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

public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

客户端

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
Resume resume = new Resume("xyy", "girl");
Resume resume1 = null;
Resume resume2 = null;
try {
resume1 = (Resume) resume.clone();
resume2 = (Resume) resume.clone();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(resume2.getName());
}

如果有引用类型的属性呢?

工作经历类
希望工作经历类对外不可见,所以没有提供含参构造方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class WorkExperience implements Cloneable {
private String date;
private String company;

public String getDate() { return date; }
public void setDate(String date) { this.date = date; }

public String getCompany() { return company; }
public void setCompany(String company) { this.company = company; }

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

简历类

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
public class Resume2 implements Cloneable {
private String name;
private String sex;
private WorkExperience workExperience;

public Resume2(String name, String sex) {
this.name = name;
this.sex = sex;
}
private Resume2(WorkExperience workExperience) {
try {
this.workExperience = (WorkExperience)workExperience.clone();
} catch (Exception e) {
e.printStackTrace();
}
}

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

public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }

public WorkExperience getWorkExperience() { return workExperience; }
public void setWorkExperience(String date, String company) {
if (this.workExperience != null) {
this.getWorkExperience().setDate(date);
this.getWorkExperience().setCompany(company);
} else {
WorkExperience workExperience = new WorkExperience();
workExperience.setDate(date);
workExperience.setCompany(company);
this.workExperience = workExperience;
}

}

@Override
public Object clone() throws CloneNotSupportedException {
Resume2 obj = new Resume2(this.workExperience);
obj.name = this.name;
obj.sex = this.sex;
return obj;
}
}

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
Resume2 resume = new Resume2("xyy", "girl");
System.out.println(resume);
resume.setWorkExperience("2020", "zjut");
Resume2 resume1 = null;
Resume2 resume2 = null;
try {
resume1 = (Resume2) resume.clone();
resume2 = (Resume2) resume.clone();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(resume2.getName());
System.out.println(resume2.getWorkExperience().getCompany());
}

本文部分内容改编于程杰老师的《大话设计模式》