设计模式——原型模式

原型模式

用一个已经创建的对象作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

原型模式包含如下角色:

  • 抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

类图请添加图片描述

原型模式的克隆分为浅克隆和深克隆。
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

浅克隆案例

用浅克隆生成学生奖状

类图

在这里插入图片描述

奖状类代码

/**
 * @author Watching
 * * @date 2023/3/16
 * * Describe:
 */
public class Citations implements Cloneable {
    public Citations() {
        System.out.println("执行构造方法");
    }
    private Student student = new Student();

    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    @Override
    protected Citations clone() throws CloneNotSupportedException {
        System.out.println("执行克隆方法");
        return (Citations) super.clone();
    }
}

Student为一个引用类型的成员变量

测试类代码

/**
 * @author Watching
 * * @date 2023/3/16
 * * Describe:
 * 浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象
 * 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citations citations = new Citations();
        Citations clone = citations.clone();

        //浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象
        System.out.println(citations == clone);//结果为false
        System.out.println(citations.getStudent() == clone.getStudent());//结果为true

        citations.getStudent().setName("张三");
        clone.getStudent().setName("李四");
        System.out.println(citations.getStudent().getName());
        //结果是李四,说明clone对象修改Student类型的变量导致citations中的变量修改了。
        //说明两个对象的Student引用都是指向的同一个地址
    }
}

根据结果可以得出结论,实现Cloneable接口使用clone()方法生成的对象是浅拷贝。

深克隆案例

这里我们使用对象流序列化来实现深克隆,我们在破坏单例模式中也使用过对象流序列化
奖状类代码
奖状类代码基本不变,唯一不同的就是不需要实现Cloneable接口了,因为我们这个案例不需要使用clone()方法来克隆对象。并且需要实现一个Serializable接口,因为需要序列化。而且Cations奖状类中的引用成员变量也需要实现Serializable接口,它也需要序列化

/**
 * @author Watching
 * * @date 2023/3/16
 * * Describe:
 */
public class Citations implements  Serializable {
    public Citations() {
        System.out.println("执行构造方法");
    }
    private Student student = new Student();
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
}

测试类代码
测试类代码需要做一些改变,使用序列化代替clone。

/**
 * @author Watching
 * * @date 2023/3/16
 * * Describe:
 * 深克隆:创建一个新对象,属性中引|用的其他对象也会被克隆,不再指向原有对象地址。
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        Citations citations = new Citations();

        //使用序列化深拷贝一个Citations对象出来,想要使用序列化,必须保证该类及其引用类型成员实现Serializable接口
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:\\d.txt")));
        oos.writeObject(citations);
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("D:\\d.txt")));
        Citations citations1 = (Citations) ois.readObject();
        citations.getStudent().setName("张三");
        citations1.getStudent().setName("李四");
        System.out.println(citations.getStudent().getName());//结果是张三
        //说明修改citations1中的Student类型成员变量并没有影响到citation中的成员变量
    }
}

根据结果可以得出结论,序列化是可以得到一个“完全崭新的对象的”(深拷贝)

重点

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值