侧边栏壁纸
博主头像
昂洋编程 博主等级

鸟随鸾凤飞腾远,人伴贤良品自高

  • 累计撰写 71 篇文章
  • 累计创建 79 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

原型模式

Administrator
2023-02-02 / 0 评论 / 0 点赞 / 52 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-06-14,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

定义

原型模式(Prototype Design Pattern)用一个已经创建的实例作为原型,通过复制改原型对象来创建和原型对象相同的新对象。

原型模式前段的js用的比较多

浅克隆

克隆对象中的所有变量的值与原型对象的值完全相同(引用数据类型变量存储的地址也是完全一致的)

定义原型类

  • Person类
package com.imysh.zmy.mca.designpattern.prototype.example01;

/**
 * @author zhangmy
 * @date 2023/2/2 14:01
 * @description
 */
public class Person {

    private String name;

    public String getName() {
        return name;
    }

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

    public Person(String name) {
        this.name = name;
    }
}

  • 原型类
package com.imysh.zmy.mca.designpattern.prototype.example01;

/**
 * @author zhangmy
 * @date 2023/2/2 13:46
 * @description 具体的原型对象
 */
public class ConcretePrototype implements Cloneable {

    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public ConcretePrototype() {
        System.out.println("创建原型对象成功");
    }

    public ConcretePrototype(Person person) {
        System.out.println("创建原型对象成功");
        this.person = person;
    }

    @Override
    protected ConcretePrototype clone() throws CloneNotSupportedException {
        System.out.println("开始克隆对象...");
        return (ConcretePrototype)super.clone();
    }
}

  • 测试类
/**
  * 浅拷贝测试
  * @throws CloneNotSupportedException
  */
public static void shallowTest() throws CloneNotSupportedException {
        Person p1 = new Person("张三");
        ConcretePrototype c1 = new ConcretePrototype(p1);
        ConcretePrototype c2 = c1.clone();
        Person p2 = c2.getPerson();
        p2.setName("李四");
        System.out.println("原型模式浅克隆c1对象和c2对象是同一个对象吗?" + (c1 == c2));
        System.out.println("原型模式浅克隆p1对象和p2对象是同一个对象吗?" + (p1 == p2));
    }

image-1675318702187

浅克隆的结果可以看出虽然克隆出来的对象不是同一个,但是内部的变量的值(p1、p2)都是同一个对象

深克隆

克隆对象的所有基本类型变量含有的值与原型对象完全一致(不包含引用数据类型)

深克隆需要用到序列化流的方式,这里我们将Person类和ConcretePrototype类实现序列化接口Serializable
然后修改一下复制的代码

/**
     * 深拷贝测试
     */
    public static void deepTest() throws IOException, ClassNotFoundException {
        Person p1 = new Person("张三");
        ConcretePrototype c1 = new ConcretePrototype(p1);

        // 创建对象序列化输出流
        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("a.txt"));
        // 写入文件
        outputStream.writeObject(c1);
        outputStream.close();

        // 创建对象序列化输入流
        ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("a.txt"));
        // 读取文件
        ConcretePrototype c2 = (ConcretePrototype)inputStream.readObject();
        inputStream.close();

        Person p2 = c2.getPerson();
        p2.setName("李四");
        System.out.println("原型模式浅克隆c1对象和c2对象是同一个对象吗?" + (c1 == c2));
        System.out.println("原型模式浅克隆p1对象和p2对象是同一个对象吗?" + (p1 == p2));
    }

image-1675319380190

可以看到内部对象属性person已经不是同一个对象了

原型模式的核心是克隆,浅拷贝有Object的clone() 方法(基于二级制),深拷贝的话可以使用Hutool的BeanUtil.copyProperties()方法去克隆属性。另外原型模式可以用在一些使用模板的场景(模板对象拷贝,然后填充部分变量即可),数据备份、撤销的场景、资源优化场景(IO、CPU)、复杂的依赖场景(级联依赖)、性能和安全要求的场景、同一个对象被多个修改者使用的场景等等

0

评论区