原型模式的深浅克隆区别

原型模式

在日常生活中,很多地方都会使用到复制粘贴的经典CV操作,感觉不要太舒适。其实在开发中,也有这种的形式,这就是原型模式,就是给出一个想要进行复制的对象,然后根据这个对象创建一个他的副本,以供我们的开发需要。

应用场景

其实之前我也想过,不就是个创建对象吗?一行代码的事,都不叫事儿!但是请看:
在这里插入图片描述在这里插入图片描述像这些类的创建和初始化所要消耗的资源多,并且过程十分繁琐,这对本身就身心已经疲惫不堪的开发者更是一大打击。。。

到这里我顿时觉得原型模式是真香啊。不过在利用原型模式的时候有一些注意的地方。
这里我就其中的两种实现方式:浅克隆和深克隆做个对比学习。

浅克隆和深克隆

这是一段用Java实现的简单的原型模式的实例:
//    深度克隆测试方法
    public static void deepClone() {
        Map<String,Integer> score = new HashMap<>();
        score.put("English",90);
        score.put("Math",97);
        score.put("Java",99);
        Student student = new Student(1,"Jason",score);
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(student);
            oos.close();
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
            Student student1 = (Student) ois.readObject();
            System.out.println("两个学生是否一致?:" + (student == student1));
            System.out.println("更改student的成绩单,添加C语言成绩");
            student.getStuScore().put("C",85);
            System.out.println("student:" + student);
            System.out.println("studentClone:" + student1);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
//    浅克隆测试方法
    public static void shallowClone() {
        Map<String,Integer> score = new HashMap<>();
        score.put("English",90);
        score.put("Math",97);
        score.put("Java",99);
        Student student = new Student(1,"Jason",score);
        Student studentClone = (Student) CloneTool.getClone(student);
        studentClone.setStuName("JasonClone");
        System.out.println("对象地址值是否一致?:" + (student == studentClone));
        System.out.println("Map地址值是否一致?:" + (student.getStuScore() == studentClone.getStuScore()));
        System.out.println("student:Jason:" + student.toString());
        System.out.println("student:JasonClone:" + student.toString());
        System.out.println("向student中添加C语言成绩95");
        student.getStuScore().put("C",95);
        System.out.println("studentClone的成绩单:");
        System.out.println(studentClone.getStuScore());
        student.setStuName("sdg");
        System.out.println(student.getStuName());
        System.out.println(studentClone.getStuName());
    }
测试结果

在这里插入图片描述

测试分析

从测试的结果很容易就可以看出来:
在浅克隆的方式中,Map的引用的同一个对象,更改其中一个对象的Map对另外的对象中的Map有影响,这就是浅克隆的特点,它只是完整的复制了值类型的数据,没有赋值引用对象。换句话说,就是所有的引用对象仍然指向原来的对象。
**在深克隆方式中:**可以看出,对于浅克隆的弊端做了很好的优化,这其实就是原型模式的经典实现方式。

克隆破坏单例

但是如果我们是克隆单例对象的话,我们就会破坏单例,如果采用上述的深克隆方式破坏单例和序列化破坏单例的原理一致,当然也可以利用之前提到过的方式来防止这种破坏。但是这里其实还有其他的解决方案,例如让单例对象不实现Cloneable接口,使其不能够被克隆,或者重写clone()方法,直接返回单例对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值