设计模式之原型模式
原型模式
-
原型模式结构图:
-
示例代码:
// 具体对象A,浅克隆 @Data public class ConcretePrototypeA implements Cloneable{ private String str; private List<String> list = new ArrayList<>(); public ConcretePrototypeA(String str) { this.str = str; } public ConcretePrototypeA clone(){ ConcretePrototypeA cloneType = null; try { cloneType = (ConcretePrototypeA) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return cloneType; } } // 具体对象B,深克隆 @Data public class ConcretePrototypeB implements Serializable{ private String str; private List<String> list = new ArrayList<>(); public ConcretePrototypeB(String str) { this.str = str; } public ConcretePrototypeB clone(){ try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream ops = new ObjectOutputStream(outputStream); ops.writeObject(this); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); ObjectInputStream ois = new ObjectInputStream(inputStream); return (ConcretePrototypeB)ois.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } } // 测试 public class PrototypeTest { public static void main(String[] args) { // 浅克隆测试 ConcretePrototypeA prototype = new ConcretePrototypeA("测试原型"); ConcretePrototypeA clone = prototype.clone(); System.out.println(prototype); System.out.println(clone); clone.setStr("克隆原型"); System.out.println("==================="); System.out.println(prototype); System.out.println(clone); System.out.println("======================"); prototype.getList().add("原型字符串"); clone.getList().add("克隆字符串"); System.out.println(prototype); System.out.println(clone); System.out.println("++++++++++++++++++++++++++++++++++++"); // 深克隆测试 // 浅克隆测试 ConcretePrototypeB prototypeB = new ConcretePrototypeB("测试原型B"); ConcretePrototypeB cloneB = prototypeB.clone(); clone.setStr("克隆原型B"); System.out.println("==================="); prototypeB.getList().add("原型字符串B"); cloneB.getList().add("克隆字符串B"); System.out.println(prototypeB); System.out.println(cloneB); } }
-
总结:原型模式在java中自带的是浅克隆,只需要实现Cloneable接口并重写Object.clone()方法即可,调用super.clone()方法,会直接在堆内存中以二进制流的方式进行复制,因此效率很高,但是如果类中存在引用对象属性,则原型对象和克隆对象的该属性会指向同一对象的引用.Java中深克隆通常使用序列化的方式.
优点:Java自带的原型模式基于内存的二进制流的复制,在性能上比直接new一个对象更加优良;
缺点:需要为每一个对象配置一个clone方法,clone方法在类的内部,当对已有类进行改造时,违背了开闭原则.