原型模式

设计模式/创建型设计模式

简述

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

  • 优点
    • 高性能 -> 原型模式是在内存二进制流中拷贝,要比直接 new 一个对象性能高
注意 -> 既是优点也是缺点,构造方法不会执行

UML 图

浅复制

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
/**
* 浅拷贝
* (1)JVM做了一个偷懒的拷贝动作,Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝
*(2)非常不安全
*/
@Data
public class BlueCat extends Cat implements Cloneable {

private String name;
private Color color = new Color("蓝色");

@Override
protected BlueCat clone() {
try {
return (BlueCat) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

// 颜色类
@Data
public class Color implements Cloneable, Serializable {
private String name;

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

@Override
protected 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
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
/**
* 深拷贝
* (1)深拷贝还有一种实现方式就是通过自己写二进制流来操作对象,然后实现对象的深拷贝,这个大家有时间自己实现一下
* (2)深拷贝和浅拷贝建议不要混合使用,特别是在涉及类的继承时,父类有多个引用的情况就非常复杂,建议的方案是深拷贝和浅拷贝分开实现。
*/
@Data
public class OrangeCat extends Cat implements Cloneable, Serializable {
private String name;
private Color color = new Color(“橘色”);

@Override
protected OrangeCat clone() {
try {
OrangeCat clone = (OrangeCat) super.clone();
clone.name = this.name;
clone.color = (Color) this.color.clone();
return clone;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

@Slf4j
public class Client {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 浅复制
BlueCat blueCat = new BlueCat();
blueCat.setName("蓝猫");
BlueCat shallowCat = blueCat.clone();
log.info("修改前:blueCat 名字: ---> " + blueCat.getName());
log.info("修改前:blueCat 颜色:---> " + blueCat.getColor().getName());
log.debug("修改前:shallowCat 名字: ---> " + shallowCat.getName());
log.debug("修改前:shallowCat 颜色:---> " + shallowCat.getColor().getName());
shallowCat.setName("蓝猫 -- Tom");
shallowCat.getColor().setName("蓝猫 -- Tom");
log.info(“修改后:blueCat 名字: ---> “ + blueCat.getName());
log.info(“修改后:blueCat 颜色:—> “ + blueCat.getColor().getName());
log.debug(“修改后:shallowCat 名字: ---> " + shallowCat.getName());
log.debug("修改后:shallowCat 颜色:---> " + shallowCat.getColor().getName());
// 深复制
OrangeCat orangeCat = new OrangeCat();
orangeCat.setName("大橘");
OrangeCat deepCat = orangeCat.clone();
log.info("修改前:orangeCat 名字: ---> " + orangeCat.getName());
log.info("修改前:orangeCat 颜色:---> " + orangeCat.getColor().getName());
log.debug(“修改前:deepCat 名字: ---> “ + deepCat.getName());
log.debug("修改前:deepCat 颜色:---> " + deepCat.getColor().getName());
deepCat.setName("橘肥");
deepCat.getColor().setName("橘肥");
log.info("修改后:orangeCat 名字: ---> " + orangeCat.getName());
log.info("修改后:orangeCat 颜色:---> " + orangeCat.getColor().getName());
log.debug("修改后:deepCat 名字: ---> " + deepCat.getName());
log.debug("修改后:deepCat 颜色:---> " + deepCat.getColor().getName());
//系列化实现深复制
OrangeCat serializeCat = new OrangeCat();
serializeCat.setName(“序列化 — 大橘”);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(serializeCat);
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
OrangeCat deepSerializeCat = (OrangeCat) objectInputStream.readObject();
log.info("修改前:serializeCat 名字: ---> " + serializeCat.getName());
log.info("修改前:serializeCat 颜色:---> " + serializeCat.getColor().getName());
log.debug("修改前:deepSerializeCat 名字: ---> " + deepSerializeCat.getName());
log.debug("修改前:deepSerializeCat 颜色:---> " + deepSerializeCat.getColor().getName());
deepSerializeCat.setName("序列化 -- 橘肥");
deepSerializeCat.getColor().setName("序列化 -- 橘肥");
log.info("修改后:serializeCat 名字: ---> " + serializeCat.getName());
log.info("修改后:serializeCat 颜色:---> " + serializeCat.getColor().getName());
log.debug("修改后:deepSerializeCat 名字: ---> " + deepSerializeCat.getName());
log.debug("修改后:deepSerializeCat 颜色:---> " + deepSerializeCat.getColor().getName());
}
}