当创建给定类的实例的过程很昂贵或很复杂时,可以使用原型模式。原型模式的核心是复制,Java原生就是支持。因为所有的JavaBean都继承自Object,而Object类提供一个clone()方法,可以讲一个JavaBean对象复制一份。但是,这个JavaBean必须实现一个Cloneable接口,表明这个JavaBean支持复制。
场景描述
有一个场景可以很好地来理解这个模式,就是西游记里的孙悟空,拔毛一吹瞬间变出数百个一模一样的分身。或者火影忍者中鸣人地影分身也有异曲同工之妙。下面用孙悟空地例子来看下如何实现原型模式。
代码示例
创建金箍棒
12345678910111213141516171819202122public class GoldRingedStaff implements Cloneable, Serializable {// 金箍棒高度private float height = 100.0F;// 金箍棒直径private float diameter = 10.0F;/*** 增长行为,每次调用长度和半径增加一倍*/public void grow() {this.diameter *= 2.0;this.height *= 2;}/*** 缩小行为,每次调用长度和半径减少一半*/public void shrink() {this.diameter /= 2;this.height /= 2;}}创建Monkey类,也就是大圣本尊,因为它是一只猴子
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748public class Monkey implements Cloneable, Serializable {private int height;private int weight;private GoldRingedStaff staff;private Date birthDate;public GoldRingedStaff getStaff() {return staff;}public Date getBirthDate() {return birthDate;}public Monkey() {this.staff = new GoldRingedStaff();this.birthDate = new Date();}/*** 浅克隆*/public Object clone() {Monkey temp = null;try {temp = (Monkey) super.clone();} catch (CloneNotSupportedException e) {System.out.println("Clone failed");}return temp;}/*** 深克隆*/public Object deepClone() throws IOException, ClassNotFoundException {// 将对象写出到流中ByteArrayOutputStream bo = new ByteArrayOutputStream();ObjectOutputStream oo = new ObjectOutputStream(bo);oo.writeObject(this);// 然后将对象从流中读出来ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());ObjectInputStream oi = new ObjectInputStream(bi);return oi.readObject();}}测试
1234567891011121314151617181920212223public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {Monkey monkey = new Monkey();// 浅克隆大圣Monkey copyMonkey = (Monkey) monkey.clone();System.out.println("Monkey King's birth date = " + monkey.getBirthDate());System.out.println("Copy Monkey's birth date = " + copyMonkey.getBirthDate());System.out.println("Monkey King == Copy Monkey ? " + (monkey == copyMonkey));// 浅克隆的话,金箍棒指向的对象是同一个System.out.println("Monkey King's Staff == Copy Monkey's Staff ? " + (monkey.getStaff() == copyMonkey.getStaff()));System.out.println();// 深克隆大圣Monkey deepCopyMonkey = (Monkey) monkey.deepClone();System.out.println("Monkey King's birth date = " + monkey.getBirthDate());System.out.println("Copy Monkey's birth date = " + deepCopyMonkey.getBirthDate());System.out.println("Monkey King == Copy Monkey ? " + (monkey == deepCopyMonkey));// 深克隆,所有对象都不是同一个System.out.println("Monkey King's Staff == Copy Monkey's Staff ? " + (monkey.getStaff() == deepCopyMonkey.getStaff()));}}
这个模式其实就是用了Java原生的功能,需要注意的是,使用浅克隆还是深克隆对程序影响很大,需要我们在使用过程中去考虑。本章节就到这里了。