『设计模式--创建型』原型模式的多种实现方法

it2023-02-19  81

一、简单介绍

原型模式(Prototype)是用于创建重复的对象,同时又能保证性能。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

二、实现方法

1、浅拷贝

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。

public class PrototypeExample { public static void main(String[] args) throws CloneNotSupportedException { Prototype prototype = new Prototype("Hello World"); Prototype cloneObject = (Prototype) prototype.clone(); System.out.println(prototype.hashCode() + prototype.toString()); System.out.println(cloneObject.hashCode() + cloneObject.toString()); // 浅拷贝?深拷贝? System.out.println(prototype.getType().hashCode()); System.out.println(cloneObject.getType().hashCode()); } } class Prototype implements Cloneable { private String name; private Type type; public Prototype(String name) { this.name = name; this.type = new Type(name); } // 省略getter、setter方法 @Override protected Object clone() throws CloneNotSupportedException { // 默认的克隆方法(浅拷贝) return super.clone(); } @Override public String toString() { return " " + name + " " + type.getTypeName(); } } class Type { private String typeName; // 省略getter、setter方法 }

结果:

这里我们会发现,浅拷贝后Prototype内部的Type类型的引用,依然是指向同一个实例(共享同一块内存)。

2、深拷贝

深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

深拷贝一般有两种方法,代码与上面的相似,下面只放出clone()方法的重写:

(1)、层层clone的方法

在浅拷贝的基础上实现,给引用类型的属性添加克隆方法,并且在拷贝的时候也实现引用类型的拷贝。此种方法由于要在多个地方实现拷贝方法,可能会造成混论。

class Prototype implements Cloneable { ...... @Override protected Object clone() throws CloneNotSupportedException { Prototype cloneObject = (Prototype) super.clone(); cloneObject.type = (Type) cloneObject.type.clone(); return cloneObject; } } class Type implements Cloneable{ ...... @Override protected Object clone() throws CloneNotSupportedException { // 如果该类的成员变量也有引用类型,其同样需要重写该方法 return super.clone(); } }

结果:

(2)、利用串行化来做深拷贝

为避免复杂对象中使用clone方法可能带来的换乱,可以使用串化来实现深拷贝。先将对象写到流里,然后再从流里读出来。

class Prototype implements Cloneable, Serializable{ ...... @Override protected Object clone() { Prototype prototype = null; ByteArrayOutputStream os = null; ObjectOutputStream oos = null; ByteArrayInputStream is = null; ObjectInputStream ois = null; try { // 输出到流中 os = new ByteArrayOutputStream(); oos = new ObjectOutputStream(os); oos.writeObject(this); // 从流中读出 is = new ByteArrayInputStream(os.toByteArray()); ois = new ObjectInputStream(is); prototype = (Prototype) ois.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流 try { if (os != null) { os.close(); } if (oos != null) { oos.close(); } if (is != null) { is.close(); } if (ois != null) { ois.close(); } } catch (IOException e) { e.printStackTrace(); } } return prototype; } } class Type implements Serializable{ ...... }

结果:

最新回复(0)