工厂方法造出来的对象是新的一个对象,里面的属性一般都是默认的.
而我所理解的原型模式操作的方法造出的是一个克隆体,可以看成2步:1.制造出一个对象.2.将造出的对象里面的属性按照被克隆体一样的拷过来
举个例子,那就是孙悟空和六耳猕猴的故事..
六耳猕猴除了是个new出来的猴子以外,其他所有的东西都是孙悟空那复制过来的.
这个涉及到一个浅克隆与深克隆的概念:
浅克隆:克隆出来的对象的属性中,如果存在其他对象的引用,则这个引用还是使用之前的拿一个,举个例子就是六耳猕猴换了,师傅还是唐僧,师弟还是八戒
深克隆:克隆出来的对象中的所以属性都是新的,上面的例子中,整个世界都变成了2份,六耳猕猴外加唐僧2,八戒2,天庭2,佛祖2.,,所有的东西都与被克隆的那一份无关.
先来一个浅克隆.
<span style="font-family:Microsoft YaHei;">package prototype;
import java.io.Serializable;
public class Monkey implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
private TangSanzang teacher;
public void check(Monkey ref) {
if (ref != null && ref == this) {
System.out.println("这是同一只猴子");
} else {
System.out.println("这不是同一只猴子");
}
teacher.check(ref.getTeacher());
}
public TangSanzang getTeacher() {
return teacher;
}
public void setTeacher(TangSanzang teacher) {
this.teacher = teacher;
}
@Override
public Monkey clone() throws CloneNotSupportedException {
return (Monkey) super.clone();
}
}
</span>
<span style="font-family:Microsoft YaHei;">package prototype;
import java.io.Serializable;
public class TangSanzang implements Serializable{
private static final long serialVersionUID = 1L;
public void check(TangSanzang ref) {
if (ref != null && ref == this) {
System.out.println("这是同一个唐三藏");
return;
}
System.out.println("这不是同一个唐三藏");
}
}
</span>
顺带复习建造者模式,假装猴子的创建很复杂
<span style="font-family:Microsoft YaHei;">package prototype;
public class MonkeyBuilder {
private Monkey monkey = new Monkey();
public MonkeyBuilder setTeacher(TangSanzang teacher) {
monkey.setTeacher(teacher);
return this;
}
public Monkey build() {
return monkey;
}
}
</span>
<span style="font-family:Microsoft YaHei;">@Test
public void testShallow() {
TangSanzang teacher = new TangSanzang();
Monkey monkey = new MonkeyBuilder().setTeacher(teacher).build();
try {
Monkey m2 = monkey.clone();
monkey.check(m2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}</span>
结果:
这不是同一只猴子
这是同一个唐三藏
再看看深克隆:
<span style="font-family:Microsoft YaHei;">@Test
public void testDeep() throws Exception {
TangSanzang teacher = new TangSanzang();
Monkey monkey = new MonkeyBuilder().setTeacher(teacher).build();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(monkey);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
Object o = ois.readObject();
Monkey m2=(Monkey) o;
monkey.check(m2);
}</span>
结果:
这不是同一只猴子
这不是同一个唐三藏
浅克隆只是复制了本身,其他都还是原先的,深克隆复制了整个(相关的)世界,
什么时候用深克隆,什么时候用浅克隆,具体情况还得具体分析