喵星之旅-沉睡的猫咪-原型模式

一、原型模式是什么?

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。专业称呼为“CV大法”。

对于java中,复制对象的困难在我们很可能复制了当前对象,但是对象内的引用却只是拿来了,内部深层的对象没有重新创建,所以复制出的对象和原对象存在共用的部分,相互影响。也就是所谓的浅克隆和深克隆。本文只考虑深克隆。这种克隆的功能可以使单独的工具类,也可以是对象自身功能,这里只演示对象自身功能。

二、java代码实现原型模式

原型类(需要实现序列化接口)

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
package create.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.List;

import com.alibaba.fastjson.JSON;
/**
*
* @author bunny~~我是兔子我会喵,我叫喵星兔。
* 原型模式
*/
public class MyPrototype implements Serializable {


private static final long serialVersionUID = 1L;
private String name;
private int age;
private List<String> title;
/**
* 通过序列化实现深度克隆
* @return
*/
public MyPrototype copyByIO() {
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 (MyPrototype)ois.readObject();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
/**
* 通过json实现深度克隆
* @return
*/
public MyPrototype copyByJson() {
try {
String jsonString = JSON.toJSONString(this);
return (MyPrototype) JSON.parseObject(jsonString, this.getClass());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getTitle() {
return title;
}
public void setTitle(List<String> title) {
this.title = title;
}
@Override
public String toString() {
return "MyPrototype [name=" + name + ", age=" + age + ", title=" + title + "]";
}

}

测试类

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
package create.prototype;

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

public class Test {

public static void main(String[] args) {
MyPrototype p0 = new MyPrototype();
p0.setAge(11);
p0.setName("kitty");
List<String> title = new ArrayList<>();
p0.setTitle(title );
System.out.println(p0);
MyPrototype p1 = p0.copyByIO();
p1.getTitle().add("p1");
System.out.println(p0);
System.out.println(p1);
System.out.println(p0 == p1);
System.out.println(p0.getTitle() == p1.getTitle());
MyPrototype p2 = p0.copyByJson();
p2.getTitle().add("p2");
System.out.println(p0);
System.out.println(p2);
System.out.println(p0 == p2);
System.out.println(p0.getTitle() == p2.getTitle());
}

}

三、总结

原型模式在编码过程中,绝对是所有设计模式出场频率最高的一种。正所谓“我们不是代码的生产者,我们只是代码的搬运工”。平时我们如果有一个需求,比如上传文件。这时我们不会找到相应的工具,然后去阅读操作手册(就是new对象的过程),而是找寻一个上传样例,用一种叫“CV”的技术实现在我们的代码中(原型模式),进而根据具体的环境进行调试,最终实现功能。

经典之中亦是不少原型的出现,比如“三人行必有我师”、“前事不忘后事之师”。但是是否选择原型还需进一步考虑。因为原型也不是万能的,原型的成功案例很多,但是失败的也是不少。如果各方面允许,其实不使用原型必然是安全的,当然可能不高效。当我们对对象目标了解程度足够高时,选择原型必然是事半功倍。任何的设计模式只要我们足够的掌控,都是我们手中的利器。在掌控不足的情况下也必然是手中的噩梦。

文章目录
  1. 一、原型模式是什么?
  2. 二、java代码实现原型模式
  3. 三、总结
|