ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

原型模式

2021-12-01 01:02:07  阅读:158  来源: 互联网

标签:r1 对象 clone 模式 Realizetype 原型 Student


原型模式

1.介绍

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

原型模式包含如下角色:

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

2.实现

原型模式的克隆分为浅克隆和深克隆。

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

image-20211130234740268

浅克隆实现

Java中的Object类中提供了 clone() 方法来实现浅克隆。

Cloneable 接口是上面的类图中的抽 象原型类,

而实现了Cloneable接口的子实现类就是具体的原型类。

代码如下:

具体原型类

/**
 * @author
 * @date 2021/11/30 23:12
 * 具体的原型类
 */
@Data
public class Realizetype implements Cloneable {

    private Student student;

    public Realizetype() {
        System.out.println("具体原型类创建成功");
    }

    @Override
    protected Realizetype clone() throws CloneNotSupportedException {
        System.out.println("具体原型复制成功!");
        return (Realizetype) super.clone();
    }
}

访问类(测试)

/**
 * @author
 * @date 2021/11/30 23:14
 * 测试访问类
 */
public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student("zhangsan",18);

        Realizetype r1 = new Realizetype();
        r1.setStudent(student);
        Realizetype r2 = r1.clone();

        System.out.println(r2==r1);//false
        System.out.println(r1.getStudent()== r2.getStudent());//true
    }
}

从打印结果来看,两个对象的成员属性student指向同一个地址,所以这种克隆方式属性浅克隆,

深克隆实现

序列化方式

注意:Realizetype和Student类都要实现Serializable接口

/**
 * @author
 * @date 2021/12/1 0:01
 * 序列化方式实现深克隆
 */
public class SerializePrototypeTest {
    public static void main(String[] args) throws Exception{
        Student student = new Student("zs",22);

        Realizetype r1 = new Realizetype();
        r1.setStudent(student);

        //将对象序列化 写入到磁盘
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\文件下载\\a.txt"));
        oos.writeObject(r1);
        oos.close();

        //反序列化  读取对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\文件下载\\a.txt"));
        Realizetype r2 = (Realizetype) ois.readObject();
        ois.close();

        System.out.println(r1==r2);
        System.out.println(r1.getStudent()==r2.getStudent());//false  没有指向同一个对象
    }
}

自定义clone方法实现

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable,Cloneable {
    private String name;
    private Integer age;

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

重写clone方法

/**
 * @author
 * @date 2021/11/30 23:12
 * 具体的原型类
 */
@Data
public class Realizetype implements Cloneable , Serializable {

    private Student student;

    public Realizetype() {
        System.out.println("具体原型类创建成功");
    }

    /**
     * 自定义clone方法实现深克隆
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Realizetype clone() throws CloneNotSupportedException {
        //先对对象进行浅克隆
        Realizetype realizetype = (Realizetype) super.clone();

        //将成员属性设置成一个新的对象  把原来的值set进去
        //或者成员属性也重写重写clone方法  我们使用clone方法复制即可  但是如果很深的话就很烦(成员对象内部又有自己的非基本类型成员对象)
        Student student = realizetype.getStudent();//目前执行同一个地址
        Student newStu = student.clone();
        realizetype.setStudent(newStu);
        return realizetype;
    }
}

测试

/**
 * @author
 * @date 2021/11/30 23:14
 * 测试访问类
 */
public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student("zhangsan",18);

        Realizetype r1 = new Realizetype();
        r1.setStudent(student);
        Realizetype r2 = r1.clone();

        System.out.println(r2==r1);//false
        System.out.println(r1.getStudent()== r2.getStudent());//false
    }
}

观察测试结果 发现实现了深拷贝

3.使用场景

  • 对象的创建非常复杂,可以使用原型模式快捷的创建对象。

  • 新对象和就对象的大部分属性都一样

  • 性能和安全要求比较高。(无需新建对象再去一个一个set属性,clone是native方法,性能高)

标签:r1,对象,clone,模式,Realizetype,原型,Student
来源: https://www.cnblogs.com/cutesheep/p/15627179.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有