原型模式

    技术2022-07-15  79

    文章目录

    原型模式

    原型模式

    原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    优点 :

    性能提高。

    逃避构造函数的约束。

    缺点:

    配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。

    必须实现 Cloneable 接口。

    使用场景 :

    1、资源优化场景。

    2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。

    3、性能和安全要求的场景。

    4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。

    5、一个对象多个修改者的场景。

    6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

    7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体,大家可以随手拿来使用。

    注意事项

    与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。Cloneable接口克隆只能克隆引用,基础类型,String类型,实际的Object对象是不会克隆的

    基本的克隆目标对象

    public class DeepCloneableTarget implements Serializable, Cloneable { private static final long serialVersionUID = 1L; private String cloneName; private String cloneClass; //构造器 public DeepCloneableTarget(String cloneName, String cloneClass) { this.cloneName = cloneName; this.cloneClass = cloneClass; } //因为该类的属性,都是String , 因此我们这里使用默认的clone完成即可 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }

    深拷贝实现

    public class DeepProtoType implements Serializable, Cloneable{ public String name; //String 属性 public DeepCloneableTarget deepCloneableTarget;// 引用类型 public DeepProtoType() { super(); } //深拷贝 - 方式 1 使用clone 方法 @Override protected Object clone() throws CloneNotSupportedException { //这里完成对基本数据类型(属性)和String的克隆 Object deep = super.clone(); //对引用类型的属性,进行单独处理 DeepProtoType deepProtoType = (DeepProtoType) deep; if (Objects.nonNull(deepCloneableTarget)) { deepProtoType.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone(); } return deepProtoType; } //深拷贝 - 方式2 通过对象的序列化实现 (推荐) public Object deepClone() { //创建流对象 ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; ByteArrayInputStream bis = null; ObjectInputStream ois = null; try { //序列化 bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(this); //当前这个对象以对象流的方式输出 //反序列化 bis = new ByteArrayInputStream(bos.toByteArray()); ois = new ObjectInputStream(bis); return ois.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { //关闭流 try { bos.close(); oos.close(); bis.close(); ois.close(); } catch (Exception e2) { System.out.println(e2.getMessage()); } } return null; } }

    测试

    public class Client { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub DeepProtoType p = new DeepProtoType(); p.name = "宋江"; p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛"); //方式1 完成深拷贝 DeepProtoType p2 = (DeepProtoType) p.clone(); System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode()); System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode()); //方式2 完成深拷贝 DeepProtoType p3 = (DeepProtoType) p.deepClone(); System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode()); System.out.println("p3.name=" + p.name + "p3.deepCloneableTarget=" + p3.deepCloneableTarget.hashCode()); } }

    结果

    Processed: 0.014, SQL: 9