原型模式
属于创建者模式
原型对象负责创建需要用到的对象, 使用者直接拷贝原型,作为创建的对象
注意, 是拷贝, 不是引用; 核心点是object对象的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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
public class Sheep implements Cloneable, Serializable { @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", master=" + master + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Master getMaster() { return master; } public void setMaster(Master master) { this.master = master; } private String name; private Master master;
@Override public Object clone() throws CloneNotSupportedException { return super.clone(); }
public Object deepCloneAbandon() throws CloneNotSupportedException { Sheep clone=(Sheep) super.clone(); clone.master=(Master) this.master.clone(); return clone; }
public Object deepClone() throws CloneNotSupportedException { ByteArrayOutputStream byteArrayOutputStream = null; ObjectOutputStream objectOutputStream = null; ByteArrayInputStream byteArrayInputStream = null; ObjectInputStream objectInputStream = null; try { byteArrayOutputStream = new ByteArrayOutputStream(); objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(this);
byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); objectInputStream = new ObjectInputStream(byteArrayInputStream); return objectInputStream.readObject(); } catch (IOException iOException) { iOException.printStackTrace(); return null; } catch (ClassNotFoundException classNotFoundException) { classNotFoundException.printStackTrace(); return null; } finally { try { byteArrayOutputStream.close(); objectOutputStream.close(); byteArrayInputStream.close(); objectInputStream.close(); } catch (IOException iOException) { iOException.printStackTrace(); } } } }
@Test public void testPrototype() throws CloneNotSupportedException { Sheep sheep = new Sheep(); sheep.setName("喜洋洋"); sheep.setMaster(new Master("村长")); Sheep copysheep = (Sheep) sheep.clone(); System.out.println(sheep.hashCode() + " " + sheep.toString()); System.out.println(copysheep.hashCode() + " " + copysheep.toString());
System.out.println("人工再拷贝实现深拷贝"); Sheep deepCopySheepAbandon = (Sheep) sheep.deepCloneAbandon(); System.out.println(deepCopySheepAbandon.hashCode() + " " + deepCopySheepAbandon.toString());
System.out.println("用流深拷贝"); Sheep deepCopySheep = (Sheep) sheep.deepClone(); System.out.println(deepCopySheep.hashCode() + " " + deepCopySheep.toString()); }
|
Spring中应用
bean的scope属性可以指定为prototype
原型模式, 每次创建bean时都是clone创建;
注意(缺点)
在实现深度克隆时, 代码复杂
需要给每个类写克隆方法, 对于已有不支持clone的类,工作量大,而且违背了开闭原则
Anything can go right will go right