Java编程开发设计模式之--原型模式(Prototype)

        原型模式Prototype是指将一个对象作为原型模板,根据它进行复制,克隆,产生一个和原型对象相似的新的对象。本文将通过对对象的浅复制与深复制的概念与具体实现,进行讲述,并通过测试类类代码展示二者区别。在JAVA语言中,复制对象是通过实现Cloneable 接口来实现的。

         先来建立原型类,Photo类

Code:

public class Photo implements Cloneable{

    @Override
    public Object clone() throws CloneNotSupportedException {
        Photo photo = (Photo) super.clone();
        return photo;
    }
}
         这是一个简单的原型类,仅需要实现Cloneable接口,覆写clone方法即可。这里引出Clone的两种方式:

浅复制:根据一个对象复制,得到的新的对象,其基本数据类型都会重新创建,但是引用类型,与原对象拥有相同的指向。

深复制:根据一个对象复制,得到的新的对象,除了基本数据类型重建,引用类型也都是重新创建的,也就是说深复制是对原型对象进行了完全彻底的复制,而浅复制不彻底。

        这里通过代码分别实现浅复制和深复制

为Photo 类新增两个属性参数,记录其是否高清照片,拍摄地点:

public class Photo implements Cloneable, Serializable {
    private PhotoLocation mLocation;

    public Photo() {
        mLocation = new PhotoLocation();
    }

    public Photo(PhotoLocation location) {
        this.mLocation = location;
    }

    public boolean ismIsHighQuality() {
        return mIsHighQuality;
    }

    public void setmIsHighQuality(boolean mIsHighQuality) {
        this.mIsHighQuality = mIsHighQuality;
    }

    private boolean mIsHighQuality = true;

    public PhotoLocation getmLocation() {
        return mLocation;
    }

    public void setmLocation(PhotoLocation mLocation) {
        this.mLocation = mLocation;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Photo photo = (Photo) super.clone();
        return photo;
    }

    public Object 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 ois.readObject();

    }
}

这里我们要实现深复制,使用的方法是采用流的形式读入当前对象的二进制输入,再写出二进制数据对应的对象
 
 
PhotoLocation 类:
public class PhotoLocation implements Serializable {
    String ID;
    String Name;

    public PhotoLocation() {

    }

    public PhotoLocation(String id, String name) {
        setID(id);
        setName(name);
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }


    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

}
     最后写测试类,显示浅复制与深复制的区别:
public class WorkClass {
    public void test() {
        Photo photo = new Photo(new PhotoLocation("010","Beijing"));
        Photo photoCopy = null;
        Photo photoDeepcopy = null;
        try {
            photoCopy = (Photo) photo.clone();
            photoDeepcopy = (Photo) photo.deepClone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (null != photo && null != photoCopy && null != photoDeepcopy) {
            System.out.println(String.format("photo.getmLocation().getName()=%s,photoCopy.getmLocation().getName()=%s,,photoDeepcopy.getmLocation().getName()=%s", photo.getmLocation().getName(), photoCopy.getmLocation().getName(), photoDeepcopy.getmLocation().getName()));
            System.out.println(String.format("photo.ismIsHighQuality()=%s,photoCopy.ismIsHighQuality()=%s,,photoDeepcopy.ismIsHighQuality()=%s", photo.ismIsHighQuality(), photoCopy.ismIsHighQuality(), photoDeepcopy.ismIsHighQuality()));
            photoCopy.getmLocation().setName("Shanghai");
            photoCopy.setmIsHighQuality(false);
            System.out.println(String.format("photo.getmLocation().getName()=%s,photoCopy.getmLocation().getName()=%s,,photoDeepcopy.getmLocation().getName()=%s", photo.getmLocation().getName(), photoCopy.getmLocation().getName(), photoDeepcopy.getmLocation().getName()));
            System.out.println(String.format("photo.ismIsHighQuality()=%s,photoCopy.ismIsHighQuality()=%s,,photoDeepcopy.ismIsHighQuality()=%s", photo.ismIsHighQuality(), photoCopy.ismIsHighQuality(), photoDeepcopy.ismIsHighQuality()));
            photoDeepcopy.getmLocation().setName("Hangzhou");
            photoDeepcopy.setmIsHighQuality(false);
            System.out.println(String.format("photo.getmLocation().getName()=%s,photoCopy.getmLocation().getName()=%s,,photoDeepcopy.getmLocation().getName()=%s", photo.getmLocation().getName(), photoCopy.getmLocation().getName(), photoDeepcopy.getmLocation().getName()));
            System.out.println(String.format("photo.ismIsHighQuality()=%s,photoCopy.ismIsHighQuality()=%s,,photoDeepcopy.ismIsHighQuality()=%s", photo.ismIsHighQuality(), photoCopy.ismIsHighQuality(), photoDeepcopy.ismIsHighQuality()));

        }
    }
}

输出结果:
I/System.out: photo.getmLocation().getName()=Beijing,photoCopy.getmLocation().getName()=Beijing,,photoDeepcopy.getmLocation().getName()=Beijing
I/System.out: photo.ismIsHighQuality()=true,photoCopy.ismIsHighQuality()=true,,photoDeepcopy.ismIsHighQuality()=true
I/System.out: photo.getmLocation().getName()=Shanghai,photoCopy.getmLocation().getName()=Shanghai,,photoDeepcopy.getmLocation().getName()=Beijing
I/System.out: photo.ismIsHighQuality()=true,photoCopy.ismIsHighQuality()=false,,photoDeepcopy.ismIsHighQuality()=true
I/System.out: photo.getmLocation().getName()=Shanghai,photoCopy.getmLocation().getName()=Shanghai,,photoDeepcopy.getmLocation().getName()=Hangzhou
I/System.out: photo.ismIsHighQuality()=true,photoCopy.ismIsHighQuality()=false,,photoDeepcopy.ismIsHighQuality()=false
    

    分析结果:可以看出photo作为原型对象,其属性参数Location(引用类型)会随着其浅复制对象photoCopy而改变,而不会随着其深复制对象photoDeepcopy而改变,另外基础类型boolean IsHighQuality 一直不会随复制对象改变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值