6、原型模式—深浅克隆

原型模式(ProtoType):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

UML图:


package com.thpin.repository.designpattern;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class PrototypeDemo {
    public static void main(String[] args) throws Exception {
        ShallowCloneAttribute sca = new ShallowCloneAttribute(1, "attr");
        ShallowCloneObject sco = new ShallowCloneObject(1, "a",sca);
        ShallowCloneObject sco1 = sco.clone();
        System.out.println(sco);
        System.out.println(sco1);
        sco1.setStr("b");
        sco1.getAttr().setAttrStr("b");
        System.out.println(sco);
        System.out.println(sco1);
        
        DeepCloneAttribute dca = new DeepCloneAttribute(10, "A");
        DeepCloneObject dco = new DeepCloneObject(10, "A", dca);
        DeepCloneObject dco1 = dco.deepClone();
        System.out.println(dco);
        System.out.println(dco1);
        dco1.setStr("B");
        dco1.getAttr().setAttrStr("B");
        System.out.println(dco);
        System.out.println(dco1);
    }
}

/*
 * 浅克隆,实现Cloneable
 */
class ShallowCloneObject implements Cloneable {
    private int n;
    private String str;
    private ShallowCloneAttribute attr;
    public ShallowCloneObject(int n, String str, ShallowCloneAttribute attr) {
        this.n = n;
        this.str = str;
        this.attr = attr;
    }
    public int getN() {
        return n;
    }
    public void setN(int n) {
        this.n = n;
    }
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    public ShallowCloneAttribute getAttr() {
        return attr;
    }
    public void setAttr(ShallowCloneAttribute attr) {
        this.attr = attr;
    }
    @Override
    public String toString() {
        return "ShallowCloneObject [n=" + n + ", str=" + str + ", attr=" + attr + "]";
    }
    public ShallowCloneObject clone() {
        Object obj = null;
        try {
            obj = super.clone();
            return (ShallowCloneObject) obj;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

/*
 * 浅克隆属性
 */
class ShallowCloneAttribute implements Cloneable {
    private int attrN;
    private String attrStr;
    public ShallowCloneAttribute(int attrN, String attrStr) {
        super();
        this.attrN = attrN;
        this.attrStr = attrStr;
    }
    public int getAttrN() {
        return attrN;
    }
    public void setAttrN(int attrN) {
        this.attrN = attrN;
    }
    public String getAttrStr() {
        return attrStr;
    }
    public void setAttrStr(String attrStr) {
        this.attrStr = attrStr;
    }
    @Override
    public String toString() {
        return "ShallowCloneAttribute [attrN=" + attrN + ", attrStr=" + attrStr + "]";
    }
    public ShallowCloneAttribute clone() {
        Object obj = null;
        try {
            obj = super.clone();
            return (ShallowCloneAttribute) obj;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

/*
 * 深克隆,实现Serializable。
 * 用序列化流重新生成对象
 */
class DeepCloneObject implements Serializable {
    private static final long serialVersionUID = 1519509451211402382L;
    private int n;
    private String str;
    private DeepCloneAttribute attr;
    public DeepCloneObject(int n, String str, DeepCloneAttribute attr) {
        this.n = n;
        this.str = str;
        this.attr = attr;
    }
    public int getN() {
        return n;
    }
    public void setN(int n) {
        this.n = n;
    }
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    public DeepCloneAttribute getAttr() {
        return attr;
    }
    public void setAttr(DeepCloneAttribute attr) {
        this.attr = attr;
    }
    @Override
    public String toString() {
        return "DeepCloneObject [n=" + n + ", str=" + str + ", attr=" + attr + "]";
    }
    public DeepCloneObject deepClone() throws IOException, ClassNotFoundException {
        // 将对象写入流中
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bao);
        oos.writeObject(this);
        // 将对象从流中取出
        ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (DeepCloneObject) ois.readObject();
    }
}

/*
 * 深克隆属性
 */
class DeepCloneAttribute implements Serializable {
    private static final long serialVersionUID = 4073693486556953564L;
    private int attrN;
    private String attrStr;
    public DeepCloneAttribute(int attrN, String attrStr) {
        this.attrN = attrN;
        this.attrStr = attrStr;
    }
    public int getAttrN() {
        return attrN;
    }
    public void setAttrN(int attrN) {
        this.attrN = attrN;
    }
    public String getAttrStr() {
        return attrStr;
    }
    public void setAttrStr(String attrStr) {
        this.attrStr = attrStr;
    }
    @Override
    public String toString() {
        return "DeepCloneAttribute [attrN=" + attrN + ", attrStr=" + attrStr + "]";
    }
}

结果:

ShallowCloneObject [n=1, str=a, attr=ShallowCloneAttribute [attrN=1, attrStr=attr]]
ShallowCloneObject [n=1, str=a, attr=ShallowCloneAttribute [attrN=1, attrStr=attr]]
ShallowCloneObject [n=1, str=a, attr=ShallowCloneAttribute [attrN=1, attrStr=b]]
ShallowCloneObject [n=1, str=b, attr=ShallowCloneAttribute [attrN=1, attrStr=b]]
DeepCloneObject [n=10, str=A, attr=DeepCloneAttribute [attrN=10, attrStr=A]]
DeepCloneObject [n=10, str=A, attr=DeepCloneAttribute [attrN=10, attrStr=A]]
DeepCloneObject [n=10, str=A, attr=DeepCloneAttribute [attrN=10, attrStr=A]]

DeepCloneObject [n=10, str=B, attr=DeepCloneAttribute [attrN=10, attrStr=B]]

观察结果中的红字,不难发现浅克隆只能真正考基本数据类型和String,而引用类型还是原来的,前后两个对象指向相同的地址,一变都变。而深克隆实现了所有类型的拷贝,拷贝前后的两个对象除了所属类型相同值相同,没有内存地址上的关联。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值