原型模式:通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建。
原型模式有以下几种方式:简单形式(new一个对象),浅克隆,深克隆
前面两种方式比较简单,我直接用深克隆来实现,深克隆是通过流的方式来实现兑现对象的克隆。
猴子类:
package prototype; import java.io.*; import java.util.Date; public class Monkey implements Cloneable,Serializable { //身高 private int height; //体重 private int weight; //生日 private Date birthDate; //金箍棒 private GoldRingedStaff staff; public Monkey(Date birthDate, GoldRingedStaff staff) { this.birthDate = birthDate; this.staff = staff; } @Override protected Object clone(){ Monkey monkey = null; try{ monkey = (Monkey)super.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { return monkey; } } 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){ return null; } } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } public Date getBirthDate() { return birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } public GoldRingedStaff getStaff() { return staff; } public void setStaff(GoldRingedStaff staff) { this.staff = staff; } }
金箍棒类:
package prototype; import java.io.Serializable; public class GoldRingedStaff implements Serializable { private float height = 100.0f; private float diameter = 10.0f; /** * 增长行为,每次调用长度和半径增加一倍 */ public void grow(){ this.diameter *= 2; this.height *= 2; } /** * 缩小行为,每次调用长度和半径减少一半 */ public void shrink(){ this.diameter /= 2; this.height /= 2; } }
客户端类:
package prototype; import java.util.Date; public class Client { private Monkey monkey = new Monkey(new Date(),new GoldRingedStaff()); public void change(){ //克隆大圣本尊 Monkey copyMonkey = (Monkey) monkey.deepClone(); System.out.println("大圣本尊的生日是:" + monkey.getBirthDate()); System.out.println("克隆的大圣的生日是:" + monkey.getBirthDate()); System.out.println("大圣本尊跟克隆的大圣是否为同一个对象 " + (monkey == copyMonkey)); System.out.println("大圣本尊持有的金箍棒 跟 克隆的大圣持有的金箍棒是否为同一个对象? " + (monkey.getStaff() == copyMonkey.getStaff())); } public static void main(String[] args) { Client client = new Client(); client.change(); } }
运行结果:
大圣本尊的生日是:Tue Aug 28 22:27:35 CST 2018 克隆的大圣的生日是:Tue Aug 28 22:27:35 CST 2018 大圣本尊跟克隆的大圣是否为同一个对象 false 大圣本尊持有的金箍棒 跟 克隆的大圣持有的金箍棒是否为同一个对象? false