设计模式:原型模式

概述
当我们创造一个类的一个实例很复杂,并且需要创建多个这样的类的实例时,如果用new操作符去创建这样的类实例,这会增加类的复杂度和耗费更多的内存空间,因为这样在内存中分配了多个一样的类实例对象,如果采用工厂模式创建的话,随着产品类的不断增加,导致子类数量不断增多,又会增加系统的复杂度。原型模式的思想是:只创建一个类实例对象,如果后面需要更多的类实例,可以通过原来的对象拷贝一份来完成创建,这样在内存中不需要创建多个相同的类实例。


原型类需要具备两个条件

  • 实现Cloneable接口(在java虚拟机中,只有实现了这个接口的类才可以被拷贝)
  • 重写Object类中的clone方法

浅拷贝和深拷贝
浅拷贝:只拷贝基本数据类型,对于对象会将引用指向同一个。
深拷贝:所有数据都复制一份。

下面看一下浅复制的代码:

package ShallowCopy;

/**
 * Created with IntelliJ IDEA.
 * User: YEN
 * Date: 2016/7/26
 * Time: 20:17
 */
public class ShallowCopy {
    //名称
    public   String name;
    //数组
    public int[] arr = new int[10];

}
package ShallowCopy;

/**
 * Created with IntelliJ IDEA.
 * User: YEN
 * Date: 2016/7/26
 * Time: 20:18
 */

//浅复制实例
public class ShallowCopyTest {
    public static void main(String[] args) {

        //创建对象A
        ShallowCopy A=new ShallowCopy();

        //给A赋值
        A.name="YEN";
        for (int i = 0; i < 10; i++) {
            A.arr[i]=i;
        }

        //创建对象B
        ShallowCopy B=A;

        System.out.println("\n.............修改A前的A...................");
        ShowArr(A);
        System.out.println("\n.............修改A前的B...................");
        ShowArr(B);


        //修改A中的数组的值
        A.name="yen";
        A.arr[0]=100;

        System.out.println("\n.............修改A后的A...................");
        ShowArr(A);
        System.out.println("\n.............修改A后的B...................");
        ShowArr(B);
    }

    public static void ShowArr(ShallowCopy temp){
        System.out.println("名称:"+temp.name);
        System.out.print("数组:");
        for (int i = 0; i <temp.arr.length ; i++) {
            System.out.print(temp.arr[i]+"     ");
        }
    }

}

这里写图片描述

可以看出:当A对象的信息修改后,B信息的也会更着改变,所以他们的数据其实是指向了同一个引用,这显然不是我们想要的。

而深拷贝则是把所有数据都拷贝一分,两个对象互不影响。

利用序列化实现深度克隆
把对象写到流里的过程是序列化(Serialization)过程;而把对象从流中读出来的过程则叫反序列化(Deserialization)过程。应当指出的是,写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。
  在Java语言里深度克隆一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的拷贝)写到一个流里(序列化),再从流里读回来(反序列化),便可以重建对象。
  

public class DeepClone  {

    public Object DeepClone() throws IOException, ClassNotFoundException {
        //将对象写到流里
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(baos);
        oos.writeObject(this);

        //从流中读回来
        ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois=new ObjectInputStream(bais);
        return ois.readObject();
    }
}

下面通过一个例子来说明:

package DeepCopy;

import java.io.*;

/**
 * Created with IntelliJ IDEA.
 * User: YEN
 * Date: 2016/7/26
 * Time: 20:46
 */
public class DeepClone implements Cloneable,Serializable {

    private String name;
    private int age;

    //构造函数
    DeepClone(){
        this.name="YEN";
        this.age=20;
    }

    //通过克隆方法
    public Object clone() throws CloneNotSupportedException {
        DeepClone temp=(DeepClone)super.clone();
        return temp;
    }

    //通过序列化与反序列化方法
    public Object DeepClone() throws IOException, ClassNotFoundException {
        //将对象写到流里
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(baos);
        oos.writeObject(this);

        //从流中读回来
        ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois=new ObjectInputStream(bais);
        return ois.readObject();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
package DeepCopy;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: YEN
 * Date: 2016/7/26
 * Time: 20:58
 */
public class DeepCloneTest {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        DeepClone A=new DeepClone();
        DeepClone B= (DeepClone) A.clone();
        DeepClone C= (DeepClone) A.DeepClone();

        System.out.println("==================修改A前=========================");

        System.out.println("A name:"+A.getName());
        System.out.println("A age:"+A.getAge());
        System.out.println(".........................................");
        System.out.println("B name:"+B.getName());
        System.out.println("B age:"+B.getAge());
        System.out.println(".........................................");
        System.out.println("C name:"+C.getName());
        System.out.println("C age:"+C.getAge());

        A.setName("yen");
        A.setAge(19);

        System.out.println("==================修改A后=========================");
        System.out.println("A name:"+A.getName());
        System.out.println("A age:"+A.getAge());
        System.out.println(".........................................");
        System.out.println("B name:"+B.getName());
        System.out.println("B age:"+B.getAge());
        System.out.println(".........................................");
        System.out.println("C name:"+C.getName());
        System.out.println("C age:"+C.getAge());


    }
}

这里写图片描述


原型模式在生成比较复杂对象的环境中比较适用,通过克隆已有对象来实现创建新的对象,节省了时间和空间。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值