原型模式

Posted by 石玉军 on 2018-07-26

引言:通过给出一个原型对象来指明所创建的对象的类型,然后复制这个原型对象来创作同类型的对象

Java中使用原型模式必须要满足的条件如下:

1.对于任何对象都有x.clone()!=x 。(也就是说克隆的对象和原先的对象不是一个对象)

2.x.clone().getClass()==x.getClass().(克隆出来的对象跟被克隆的对象是类型一样)

3.x.clone().equals(x)。(克隆对象的属性应该是与被克隆的对象的属性完全一样的)

一个简单的原型模型的类图应该是这样的:

图片

Prototype:抽象接口,所有具体原型类应该实现的接口

User:具体原型类

Client:提出clone请求的客户端角色

PrototypeManage:对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
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
public interface Prototype extends Cloneable{
public Object clone();

public void setName(String name);

public String getName();

public boolean equals(Object obj);

}
public class User implements Prototype {
private String name;

@Override
public synchronized Object clone() {
Prototype p=null;
try {
p=(Prototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}

@Override
public void setName(String name) {
this.name=name;
}
public String getName(){
return this.name;
}
@Override
public boolean equals(Object prototype) {
if(prototype instanceof Prototype){
if(this.getName()==null&&((Prototype) prototype).getName()==null){
return true;
}
if(this.getName()==null&&((Prototype) prototype).getName()!=null){
return false;
}
if(this.getName()!=null&&((Prototype) prototype).getName()==null){
return false;
}
if(this.getName().equals(((Prototype) prototype).getName())){
return true;
}
}
return false;
}

}
public class PrototypeManage {
private Vector vector=new Vector();

public void add(Prototype p){
vector.add(p);
}
public Prototype get(int i){
return (Prototype)vector.get(i);
}
public int size(){
return vector.size();
}
}
public class Client {
private static Prototype p;
private static PrototypeManage prototypeManage;

public static void main(String[] args){
p=new User();
p.setName("zhang3");
prototypeManage=new PrototypeManage();
Prototype user=(Prototype) p.clone();
System.out.println(p.equals(user));
prototypeManage.add(user);

}
}

执行上述代码我们发现prototypeManage中所管理的user与第一次我们创建的原型对象相比较是符合我们上方定义的三个条件的。

深克隆和浅克隆
在Java中存在这个现象,如果被克隆对象中存在一个Dog类对象dog,克隆出来的对象如果指向的仍然是dog的话,那么这个clone就是浅克隆。如果在此克隆过程中dog也被克隆一份的话那么此次克隆就是深克隆。