原型模式
参照了许多大佬的博客,这里先给出自己一些关于原型模式的理解,从名字本身来讲,原型就是一个model,就像前人造的轮子的蓝图,你依葫芦画瓢再克隆出来一个不就行了,思想还是很简单的,关键在于它的实现
Shallow Copy
从话里听出来实现的核心就是克隆,那么就来谈谈克隆的道道,众所周知,在猿类的思想中有深拷贝和浅拷贝的操作,所谓浅拷贝就是复制对象的内容,对象中的引用、容器、数组这些复杂类型是copy他们的地址、而修改浅拷贝后的对象的基本类型或包装类型的值和原来的对象没有关系,但修改复杂类型就会跟原对象牵连了
Deep Copy
深拷贝其实就是复制一个完全不同的对象,这样强调其区别其实不为过,主要在于复杂类型的地址问题,但这两种克隆方式都是创建出了不同的对象,所以说通过具体原型类创建出来的对象和原对象的地址是不同的
说多了不好理解,写看波代码
Prototype.java
public interface Prototype { SpecificPrototype clone(); }
SpecificPrototype.java
public class SpecificPrototype implements Prototype { private int property1; private String property2; private Property property; public int getProperty1() { return property1; } public void setProperty1(int property1) { this.property1 = property1; } public String getProperty2() { return property2; } public void setProperty2(String property2) { this.property2 = property2; } public Property getProperty() { return property; } public void setProperty(Property property) { this.property = property; } @Override public SpecificPrototype clone() { SpecificPrototype specificPrototype = new SpecificPrototype(); specificPrototype.setProperty1(this.property1); specificPrototype.setProperty2(this.property2); specificPrototype.setProperty(this.property); return specificPrototype; } } /* * 实现Cloneable接口可以直接调用封装好的clone方法 * */ class SpecificPrototype1 implements Cloneable{ private int property1; private String property2; private Property property; public int getProperty1() { return property1; } public void setProperty1(int property1) { this.property1 = property1; } public String getProperty2() { return property2; } public void setProperty2(String property2) { this.property2 = property2; } public Property getProperty() { return property; } public void setProperty(Property property) { this.property = property; } public SpecificPrototype1 clone() throws CloneNotSupportedException { SpecificPrototype1 sp = (SpecificPrototype1) super.clone(); return sp; } } /* * 需要实现Cloneable和Serializable接口 * */ class SpecificPrototype2 implements Cloneable, Serializable{ private int property1; private String property2; private Property1 property; public int getProperty1() { return property1; } public void setProperty1(int property1) { this.property1 = property1; } public String getProperty2() { return property2; } public void setProperty2(String property2) { this.property2 = property2; } public Property1 getProperty() { return property; } public void setProperty(Property1 property) { this.property = property; } /* * 通过字节数组流的方式结合序列化实现深拷贝,通过内存读取的方式实现 * */ public SpecificPrototype2 deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (SpecificPrototype2) ois.readObject(); } }
Property.java
public class Property{} //需要实现序列化接口 class Property1 implements Serializable {}
Client.java
public class Client { public SpecificPrototype startClone(SpecificPrototype sp){ return sp.clone(); } } class Client1{ public SpecificPrototype1 startClone(SpecificPrototype1 sp1) throws CloneNotSupportedException { return sp1.clone(); } } class Client2{ public SpecificPrototype2 startClone(SpecificPrototype2 sp2) throws IOException, ClassNotFoundException { return sp2.deepClone(); } }
TestPrototype.java
public class TestPrototype { public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException { //简单浅拷贝 SpecificPrototype sp = new SpecificPrototype(); sp.setProperty1(1); sp.setProperty2("abc"); Property property = new Property(); sp.setProperty(property); System.out.println(sp); Client client = new Client(); SpecificPrototype prototypeClone = client.startClone(sp); System.out.println(prototypeClone); System.out.println(sp.getProperty()); System.out.println(prototypeClone.getProperty()); System.out.println("DeepClone:" + (sp.getProperty() != prototypeClone.getProperty())); //具体原型类实现Cloneable接口的浅拷贝 SpecificPrototype1 sp1 = new SpecificPrototype1(); sp1.setProperty1(1); sp1.setProperty2("abc"); Property property1 = new Property(); sp1.setProperty(property1); System.out.println(sp1); Client1 client1 = new Client1(); SpecificPrototype1 prototypeClone1 = client1.startClone(sp1); System.out.println(prototypeClone1); System.out.println(sp1.getProperty()); System.out.println(prototypeClone1.getProperty()); System.out.println("DeepClone:" + (sp1.getProperty() != prototypeClone1.getProperty())); //具体原型类实现Cloneable和Serializable接口,通过流的方式实现深拷贝 SpecificPrototype2 sp2 = new SpecificPrototype2(); sp2.setProperty1(1); sp2.setProperty2("abc"); Property1 property2 = new Property1(); sp2.setProperty(property2); System.out.println(sp2); Client2 client2 = new Client2(); SpecificPrototype2 prototypeClone2 = client2.startClone(sp2); System.out.println(prototypeClone2); System.out.println(sp2.getProperty()); System.out.println(prototypeClone2.getProperty()); System.out.println("DeepClone:" + (sp2.getProperty() != prototypeClone2.getProperty())); } }
Run result
com.ycw.prototype.SpecificPrototype@3b6eb2ec com.ycw.prototype.SpecificPrototype@6e8dacdf com.ycw.prototype.Property@7a79be86 com.ycw.prototype.Property@7a79be86 DeepClone:false com.ycw.prototype.SpecificPrototype1@21bcffb5 com.ycw.prototype.SpecificPrototype1@668bc3d5 com.ycw.prototype.Property@3cda1055 com.ycw.prototype.Property@3cda1055 DeepClone:false com.ycw.prototype.SpecificPrototype2@79b4d0f com.ycw.prototype.SpecificPrototype2@9629756 com.ycw.prototype.Property1@7c0e2abd com.ycw.prototype.Property1@62ee68d8 DeepClone:true
根据得出的结果可以看出前两个是浅拷贝,只不过后者多了个Cloneable接口,而最后一个是深拷贝,这样的结果就很好对比分析了,原型模式的分析大致如此
来源:https://www.cnblogs.com/demonycw/p/12102146.html