4.原型模式

一.原型模式介绍

 

 

二.浅拷贝

Sheep.java

public class Sheep implements Cloneable{

    private String name;
    private int age;
    private String color;
    private Sheep mother;

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


    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 String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Sheep getMother() {
        return mother;
    }

    public void setMother(Sheep mother) {
        this.mother = mother;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                ", mother=" + mother +
                '}';
    }

    @Override
    protected Object clone(){
        Object clone = null;

        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

}

PrototypeDemo.java

public class PrototypeDemo {

    public static void main(String[] args) {

        Sheep sheep1 = new Sheep("sheep1",7,"red",null);
        Sheep sheep2 = new Sheep("sheep2",3,"red",sheep1);


        Sheep sheep3 = (Sheep) sheep2.clone();

        System.out.println(sheep2.getMother().hashCode());
        System.out.println(sheep3.getMother().hashCode());

        sheep3.getMother().setName("sheep10");

        System.out.println(sheep2.getMother()); //被修改了
        System.out.println(sheep3.getMother()); //被修改了

    }
}

三.深拷贝

 

 1.方式1:重写clone方法

  • 这样如果有很多引用类型则非常麻烦,不推荐使用

  • 需要实现Cloneable(标记)接口,并重写Object的clone方法

sheep.java

public class Sheep implements Serializable, Cloneable {

    private String name;
    private Sheep mother;

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

    public String getName() {
        return name;
    }

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

    public Sheep getMother() {
        return mother;
    }

    public void setMother(Sheep mother) {
        this.mother = mother;
    }

    @Override
    protected Object clone() {

        Object clone = null;

        try {
            //对基本类型或String类型的属性进行克隆
            clone = super.clone();
            //对引用类型的属性进行克隆
            Sheep sheep = (Sheep) clone;
            if (this.mother != null) {
                sheep.mother = (Sheep) this.mother.clone();
            }
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return clone;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", mother=" + mother +
                '}';
    }
}
public class PrototypeDemo {

    public static void main(String[] args) {

        Sheep sheep1 = new Sheep("sheep1",null);
        Sheep sheep2 = new Sheep("sheep2",sheep1);

        Sheep sheep3 = (Sheep) sheep2.clone();

        System.out.println(sheep2.getMother().hashCode());  //不同的hashCode
        System.out.println(sheep3.getMother().hashCode());

    }
}

2.方式2:序列化(推荐)

  • 用于处理较多引用

  • 需要实现Serializeable(标记)接口,增加一个方法用于深拷贝

public class Sheep implements Serializable, Cloneable {

    private String name;
    private Sheep mother;

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

    public String getName() {
        return name;
    }

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

    public Sheep getMother() {
        return mother;
    }

    public void setMother(Sheep mother) {
        this.mother = mother;
    }

    @Override
    protected Object clone() {

        Object clone = null;

        try {
            //对基本类型或String类型的属性进行克隆
            clone = super.clone();
            //对引用类型的属性进行克隆
            Sheep sheep = (Sheep) clone;
            if (this.mother != null) {
                sheep.mother = (Sheep) this.mother.clone();
            }
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return clone;
    }

    //克隆的第二种方式
    public Object deepClone() {

        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(bos)) {

            //将对象写入bos中
            oos.writeObject(this);
            try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                 ObjectInputStream ois = new ObjectInputStream(bis)) {
                
                //从ois中拿出对象
                Sheep sheep = (Sheep) ois.readObject();

                return sheep;
            } catch (Exception e) {
                e.printStackTrace();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", mother=" + mother +
                '}';
    }
}
public class PrototypeDemo {

    public static void main(String[] args) {

        Sheep sheep1 = new Sheep("sheep1",null);
        Sheep sheep2 = new Sheep("sheep2",sheep1);

        Sheep sheep3 = (Sheep) sheep2.clone();

        System.out.println(sheep2.getMother().hashCode());  //不同的hashCode
        System.out.println(sheep3.getMother().hashCode());

        Sheep sheep4 = (Sheep) sheep2.deepClone();

        System.out.println(sheep2.getMother().hashCode());  //不同的hashCode
        System.out.println(sheep4.getMother().hashCode());

    }
}

四.总结

 

posted @ 2020-03-12 23:08  All_just_for_fun  阅读(119)  评论(0)    收藏  举报