原型模式

类图

代码

Prototye类

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
class People implements Cloneable, Serializable{

/**
* 浅拷贝
* @return
*/
@Override
protected Object clone() {
People people = null;

try {
people = (People) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}

return people;
}

/**
* 深拷贝
* @return
*/
public Object deepClone(){

try {
//将对象写到流里
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//从流里读回来
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}

return null;
}
}

ConcretePrototype类

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
class Men extends People{

private String name;

private Weapon weapon;

public Weapon getWeapon() {
return weapon;
}

public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}

public String getName() {
return name;
}

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

public Men(String name) {
this.name = name;
System.out.println("造人开始");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("造人结束");
}

public void run(){
System.out.println("跑步");
}

@Override
public String toString() {
return "Men{" +
"name='" + name + '\'' +
", weapon=" + weapon +
'}';
}
}

引用类(仅为了说明深拷贝和浅拷贝的区别)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Weapon implements Serializable{

private String name;

public Weapon(String name) {
this.name = name;
}

public String getName() {
return name;
}

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

@Override
public String toString() {
return "Weapon{" +
"name='" + name + '\'' +
'}';
}
}

测试类

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
public class Client {

public static void main(String args[]){

Men men1 = new Men("男性人类1号");

Weapon gun = new Weapon("AK47");

men1.setWeapon(gun);

System.out.println(men1);

Men men2 = (Men) men1.clone();
System.out.println(men2);
System.out.println("men1和men2是否是同一个人:" + men1.equals(men2));
System.out.println("men1和men2所持有的武器是否是同一把:" + men1.getWeapon().equals(men2.getWeapon()));

Men men3 = (Men) men1.deepClone();
System.out.println(men3);
System.out.println("men1和men3是否是同一个人:" + men1.equals(men3));
System.out.println("men1和men2所持有的武器是否是同一把:" + men1.getWeapon().equals(men3.getWeapon()));

}

}

运行结果

1
2
3
4
5
6
7
8
9
造人开始
造人结束
Men{name='男性人类1号', weapon=Weapon{name='AK47'}}
Men{name='男性人类1号', weapon=Weapon{name='AK47'}}
men1和men2是否是同一个人:false
men1和men2所持有的武器是否是同一把:true
Men{name='男性人类1号', weapon=Weapon{name='AK47'}}
men1和men3是否是同一个人:false
men1和men2所持有的武器是否是同一把:false

总结

概述

Prototye类承载了拷贝方法,使其实现类不用重复实现,原型模式又分

浅拷贝

引用不会进行复制

深拷贝

会复制所有引用,要保障被复制对象和对象包含的所有引用对象都实现Serialize接口

优点

当目标对象的实例化较为费时时就可以采用原型模式进行对象创建,在文中Men对象创建的过程中Sleep了2秒做了示范

缺点

如果是使用深拷贝,则其所有引用对象都必须实现Serialize接口,这个对于旧系统来讲改造成本有点大

深拷贝要注意可能会出现的循环引用问题