【设计模式】原型模式

问题:有时候需要一个和已有对象一模一样的对象时,如果用new的方式通过构造器来新造一个对象,会非常耗费资源和比较复杂。

原型模式是直接克隆出一个一模一样的对象,创建对象非常高效,无需知道对象创建细节。

原型实例指定了要创建的对象的种类。

原型模式(prototype)

原形模式的写法其实很简单,分为两步:

  • 实现Cloneable接口
  • 重写clone非法

要被克隆的类

// 图片
public class IMG implements Cloneable{//1.实现Cloneable接口
    String name = null;
    Date date = null;

    public IMG(String name, Date date) {
        this.name = name;
        this.date = date;
    }

    @Override
    public String toString() {
        return "IMG{" +
                "name='" + name + '\'' +
                ", date=" + date +
                '}';
    }

    //2.重写clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

克隆

public class CopyIMG {
    public static void main(String[] args) throws Exception {
        Date date = new Date();
        IMG img1 = new IMG("王冰冰", date);
        System.out.println("img1>"+img1);
        System.out.println("img1.hash>" + img1.hashCode());

        IMG img2 = (IMG) img1.clone();
        System.out.println("img2>"+img2);
        System.out.println("img2.hash>" + img2.hashCode());

    }
}

输出(可以看到对象的内容一致,但不是同一个对象了,hashcode的值不同)

img1>IMG{name=‘王冰冰’, date=Tue Jan 05 21:57:09 CST 2021}
img1.hash>325040804
img2>IMG{name=‘王冰冰’, date=Tue Jan 05 21:57:09 CST 2021}
img2.hash>1173230247

Process finished with exit code 0

但以上写法在某种情况下好像就不对了

预期:克隆完无论原对象怎么改变,克隆对象都是保存在克隆时那个状态,除非主动改变克隆对象。

public class CopyIMG {
    public static void main(String[] args) throws Exception {
        Date date = new Date();
        IMG img1 = new IMG("王冰冰", date);
        IMG img2 = (IMG) img1.clone();//已经克隆结束
        
        //克隆结束后修改原对象的值
        img1.getDate().setTime(45648973);

        System.out.println("img1>"+img1);
        System.out.println("img1.hash>" + img1.hashCode());

        System.out.println("img2>"+img2);
        System.out.println("img2.hash>" + img2.hashCode());

    }
}

输出

img1>IMG{name=‘王冰冰’, date=Thu Jan 01 20:40:48 CST 1970}
img1.hash>325040804
img2>IMG{name=‘王冰冰’, date=Thu Jan 01 20:40:48 CST 1970}
img2.hash>1173230247

Process finished with exit code 0


和预期的不一致,克隆后的对象应显示的时间应该要为当前的时间才对!

其实这里涉及了浅拷贝和深拷贝,学过C++的朋友应该就比较了解,这里只是单纯的把date对象的地址复制过去,而不是克隆一个新的date对象。

内存现状

在这里插入图片描述

深拷贝

修改IMG的clone方法

@Override
protected Object clone() throws CloneNotSupportedException {
    IMG clone = (IMG) super.clone();
    clone.date = (Date) date.clone();
    return clone;
}

把date对象也克隆了。

输出

img1>IMG{name=‘王冰冰’, date=Thu Jan 01 20:40:48 CST 1970}
img1.hash>325040804
img2>IMG{name=‘王冰冰’, date=Tue Jan 05 22:18:08 CST 2021}
img2.hash>1173230247

Process finished with exit code 0

内存状态

在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值