原型模式

1、示例图

在这里插入图片描述

2、代码

实现原型模式的核心类

/**
 * 1、实现Cloneable接口
 * 2、实现clone方法
 */
public class Sheep implements Cloneable{
    private String name;
    private int age;

    public Sheep(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //clone该实例使用默认的方法clone
    @Override
    protected Object clone() {
        Sheep sheep = null;
        try{
            sheep = (Sheep) super.clone();
        }catch(Exception e){
            System.out.println(e.toString());
        }
        return sheep;
    }
}

继承了Sheep

public class SheepImpl extends Sheep {
    public SheepImpl(String name, int age) {
        super(name, age);
    }
}

运行测试原型模式

public class ProtoTypeTest {
    public static void main(String[] args) {
        SheepImpl sheep = new SheepImpl("洋洋",1);
        SheepImpl cpSheep = (SheepImpl) sheep.clone();
        System.out.println(sheep == cpSheep); //为false 不是同一个对象
    }
}

3、优点

1)在解决克隆羊的问题上比用传统方式效率高,减少了在类初始化对于资源的消耗

4、浅拷贝

如果在Sheep中包含一个其他的对象的属性,在clone之前对该对象的该属性赋值,即该属性是引用对象,当该属性被修改时会影响到其他clone的对象。(注:这里的clone方法都是默认的clone方式)

Sheep类新增Sheep属性

public class Sheep implements Cloneable{
    private String name;
    private int age;
    private Sheep sheep;
}

运行代码

public class ProtoTypeTest {
    public static void main(String[] args) {
        SheepImpl sheep = new SheepImpl("洋洋",1);
        SheepImpl friend = new SheepImpl("哈哈",2);
        sheep.setSheep(friend);

        //默认使用默认的clone
        SheepImpl cpSheep = (SheepImpl) sheep.clone();

        //新增的属性Sheep的hashCode相同,即浅拷贝
        System.out.println(sheep.getName() + "--" + sheep.getAge() + "--" + sheep.getSheep().hashCode());
        System.out.println(cpSheep.getName() + "--" + cpSheep.getAge() + "--" + cpSheep.getSheep().hashCode());
        System.out.println(sheep == cpSheep); //false 不是同一个对象
    }
}

运行结果

洋洋--1--460141958
洋洋--1--460141958
false

4、深拷贝的两种方法

主要的深拷贝方法都在这个类中

public class DeepClone implements Cloneable, Serializable {
    private static final long serialVersionUID = -1464966484283440495L;
    private String name;
    private int age;
    private DeepCloneTarget deepCloneTarget;
    public DeepClone(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    public DeepCloneTarget getDeepCloneTarget() {
        return deepCloneTarget;
    }
    public void setDeepCloneTarget(DeepCloneTarget deepCloneTarget) {
        this.deepCloneTarget = deepCloneTarget;
    }

    /**
     * 深拷贝 方式1
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        DeepClone deep = null;
        //1、对基本数据类型进行clone(使用默认的clone)
        deep = (DeepClone)super.clone();
        //2、将引用对象进行,单独处理
        deep.setDeepCloneTarget((DeepCloneTarget)deepCloneTarget.clone());
        return deep;
    }

    /**
     * 深拷贝 方式2
     * 通过序列化clone
     */
    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);
            DeepClone cpDeepClone = (DeepClone) ois.readObject();
            return cpDeepClone;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }finally {
            //关闭流
            try {
                bos.close();
                bis.close();
                oos.close();
                ois.close();
            }catch (Exception e2){
                e2.printStackTrace();
            }
        }
    }
}

DeepClone的属性

public class DeepCloneTarget implements Cloneable, Serializable {
    private static final long serialVersionUID = -4163686254455988446L;
    private String Name;
    private int no;

    public DeepCloneTarget(String name, int no) {
        Name = name;
        this.no = no;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }

    //在这里全部属性都是基本数据类型,则使用默认的clone即可
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

运行代码

public class DeepCloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        DeepClone deepClone = new DeepClone("aaa",11);
        deepClone.setDeepCloneTarget(new DeepCloneTarget("vvv",22));

        //方式1 深拷贝
        DeepClone cpDeepClone = (DeepClone) deepClone.clone();

        System.out.println("深拷贝 方式1");
        System.out.println(deepClone == cpDeepClone);
        System.out.println("deepClone.DeepCloneTarget = "+deepClone.getDeepCloneTarget().hashCode());
        System.out.println("cpdeepClone.DeepCloneTarget = "+cpDeepClone.getDeepCloneTarget().hashCode());

        //方式2 深拷贝 序列化
        DeepClone cpDeepCloneSerial = (DeepClone) deepClone.deepClone();

        System.out.println("深拷贝 方式2");
        System.out.println(deepClone == cpDeepCloneSerial);
        System.out.println("deepClone.DeepCloneTarget = "+deepClone.getDeepCloneTarget().hashCode());
        System.out.println("cpDeepCloneSerial.DeepCloneTarget = "+cpDeepCloneSerial.getDeepCloneTarget().hashCode());
    }
}

运行结果

深拷贝 方式1
false
deepClone.DeepCloneTarget = 460141958
cpdeepClone.DeepCloneTarget = 1163157884
深拷贝 方式2
false
deepClone.DeepCloneTarget = 460141958
cpDeepCloneSerial.DeepCloneTarget = 2065951873
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值