21、设计模式之原型模式

import java.util.Date;

public class Pig implements Cloneable {

    private String name;

    private Date birthday;

    public String getName() {
        return name;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Pig{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}'+ super.toString();
    }
}

调用

import java.util.Date;

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Pig pig1 = new Pig();
        pig1.setName("佩奇");
        pig1.setBirthday(new Date(0L));
        System.out.println("【原始】pig1=" + pig1);

        Pig pig2 = (Pig) pig1.clone();
        System.out.println("【原始】pig2="+ pig2);

        // 调整pig1的属性值
        pig1.setName("哼哼");
        pig1.getBirthday().setTime(66666666666L);
        System.out.println("【变更】pig1=" + pig1);
        System.out.println("【变更】pig2=" + pig2);
    }
}

运行结果

我们在Main函数中之改变了pig1的生日属性,但从结果中可以看出pig2也跟着发生了变化,但是名称属性,并未跟着发生变化,由此说明,浅克隆只能使当前对象中值类型变量保持独立性,如要引用类型也保持独立性,则需要深克隆才可以

深克隆

import java.util.Date;

public class Pig implements Cloneable {

    private String name;

    private Date birthday;

    public String getName() {
        return name;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 深克隆
        Pig pig = (Pig)super.clone();
        // 将对象中引用变量也执行一下clone()方法
        pig.birthday = (Date) pig.birthday.clone();
        return pig;
    }

    @Override
    public String toString() {
        return "Pig{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}'+ super.toString();
    }
}

运行结果

这里必要的提一点,原型模式和单例模式,似乎存在一丢丢的矛盾点,那就是单例模式的类来实现Cloneable接口,这样单例模式就会失效,由此,需要特殊的针对该点做下调整,改进后的单例模式代码如下

单例模式改进版

public class Singleton implements Cloneable {

    private final static Singleton instance;

    static{
        instance = new Singleton();
    }
    private Singleton(){

    }

    private static Singleton getInstance(){
        return instance;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 注释掉一下代码,直接调用getInstance()方法,来屏蔽克隆带来的破坏性,保持单例的唯一性
        // return super.clone();
        return getInstance();
    }
}

猜你喜欢

转载自blog.csdn.net/crystalcs2010/article/details/83305772