详解JAVA 原型模式

详解JAVA 原型模式

什么是原型模式?

原型模式(Prototype Pattern),又叫克隆模式,是指通过复制已经存在的一个对象生成一个新的对象,新的对象是通过对原始对象进行复制而生成的,原始对象就可以充当新对象的一个原型。原型模式是一种创建型模式,其作用是通过把一个实例作为原型,复制出新的实例来。

原型模式的使用场景

  • 在需要创建对象的过程中,如果创建新的对象的代价比较大,而且我们已经有了一个相同对象可以直接复制,则可以使用原型模式来避免重复创建对象,以提高创建对象的效率。
  • 在需要重新组合一个对象时,如果对象内部结构比较复杂或者对象之间的相互依赖关系比较难以处理,那么可以使用原型模式来方便重新组合一个新的对象。

JAVA 实现原型模式

JAVA 实现原型模式一般需要满足以下两个条件:

  • 实现 Cloneable 接口
  • 使用 clone() 方法

实现 Cloneable 接口

Cloneable 是一个标记接口,用于表明一个类可以被复制。如果我们没有实现该接口,调用 clone() 方法会抛出 CloneNotSupportedException 异常。

使用 clone() 方法

JAVA 中的 clone() 方法是一个 protected 的方法,我们需要在自己的类中重写这个方法并将它的访问修饰符改为 public。另外,在 clone() 方法中,我们需要使用 super.clone() 方法。因为 Object 类中的 clone() 方法会为新对象分配内存,并将原始对象的值复制到新对象中。

JAVA 原型模式示例

下面通过一个示例来演示如何使用 JAVA 原型模式。

示例1:复制简单对象

假设我们有一个学生对象(Student),它有两个属性:name 和 age。我们使用原型模式来创建一个新的学生对象。

public class Student implements Cloneable {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

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

上面的代码中,我们实现了 Cloneable 接口,并重写了 clone() 方法。在 clone() 方法中,我们使用 super.clone() 方法来创建新的学生对象。然后在使用 clone() 方法创建新的学生对象时,只需要调用原始对象的 clone() 方法即可。

示例代码如下:

public class PrototypeDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student("Tom", 18);
        System.out.println("student1 = " + student1);

        Student student2 = (Student) student1.clone();
        System.out.println("student2 = " + student2);

        student2.setName("Jerry");
        student2.setAge(20);

        System.out.println("student1 = " + student1);
        System.out.println("student2 = " + student2);
    }
}

示例2:复制包含对象的对象

现在,我们来看一个更加复杂的示例。假设我们有一个学生对象(Student),它包含一个班级对象(Classroom),班级对象又包含多个学生对象。我们现在想要复制一个新的学生对象,它的班级和班级中的学生对象也需要被复制。

public class Student implements Cloneable {
    private String name;
    private int age;
    private Classroom classroom;

    public Student(String name, int age, Classroom classroom) {
        this.name = name;
        this.age = age;
        this.classroom = classroom;
    }

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

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setClassroom(Classroom classroom) {
        this.classroom = classroom;
    }

    public Classroom getClassroom() {
        return classroom;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Student student = (Student) super.clone();
        student.classroom = (Classroom) student.classroom.clone();
        return student;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", classroom=" + classroom +
                '}';
    }
}

public class Classroom implements Cloneable {
    private String className;
    private List<Student> students;

    public Classroom(String className, List<Student> students) {
        this.className = className;
        this.students = students;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getClassName() {
        return className;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    public List<Student> getStudents() {
        return students;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Classroom classroom = (Classroom) super.clone();

        List<Student> students = new ArrayList<>();
        for (Student student : classroom.getStudents()) {
            students.add((Student) student.clone());
        }
        classroom.setStudents(students);

        return classroom;
    }

    @Override
    public String toString() {
        return "Classroom{" +
                "className='" + className + '\'' +
                ", students=" + students +
                '}';
    }
}

上面的代码中,我们在 Student 类和 Classroom 类中都实现了 Cloneable 接口,并重写了 clone() 方法。在 Student 类的 clone() 方法中,我们使用 super.clone() 方法创建新的学生对象,并将班级对象也进行复制。在 Classroom 类的 clone() 方法中,我们首先通过 super.clone() 方法创建新的班级对象,然后再复制班级中的所有学生对象。

示例代码如下:

public class PrototypeDemo2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student("Tom", 18, new Classroom("ClassA", Arrays.asList(new Student("Jerry", 20, null))));
        System.out.println("student1 = " + student1);

        Student student2 = (Student) student1.clone();
        System.out.println("student2 = " + student2);

        student2.getClassroom().getStudents().get(0).setName("Jack");
        student2.getClassroom().getStudents().get(0).setAge(22);

        System.out.println("student1 = " + student1);
        System.out.println("student2 = " + student2);
    }
}

运行上述代码后,我们可以看到新创建的学生对象和班级对象都和原始对象不同,已经成功地实现了对象的深度复制。

总结

原型模式是设计模式中的一种,它可以避免重复创建对象,提高创建对象的效率。JAVA 中的原型模式需要实现 Cloneable 接口,并重写 clone() 方法。如果一个对象包含其他对象,则需要对其进行深度复制。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JAVA 原型模式 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 通过java记录数据持续变化时间代码解析

    通过Java记录数据持续变化时间代码解析 当我们需要记录某个变量的持续变化时间(即开始变化到结束变化的时间),可以通过Java代码实现。这种方式可以用于监控某个变量,例如温度、湿度等持续变化的情况,也可以用于统计某个变量的变化时长。 实现过程 我们可以定义一个Timer类,包含以下属性: startTime:变量开始变化的时间戳(毫秒) endTime:变量…

    Java 2023年5月20日
    00
  • 如何用Java Stream写出既高雅又装*的代码

    如何用Java Stream写出既高雅又装*的代码? Java Stream可以被用来解决很多问题,从简单的过滤到复杂的组合操作。它极大地减少了编写的代码量,提高了代码的可读性、可维护性和可重用性。 下面是一些使用Java Stream的技巧,可以让你写出高雅又装*的代码。 1. 使用Lambda表达式写过滤器 传统的Java代码需要明确指定每一步操作的细节…

    Java 2023年5月26日
    00
  • Java中Vector与ArrayList的区别详解

    下面是Java中Vector与ArrayList的区别详解: Vector和ArrayList的定义与创建方式 Vector和ArrayList都是容器类,用于存储Java对象。 Vector和ArrayList都实现了List接口,因此二者有很多相似之处。 Vector和ArrayList的创建方式类似,可以通过new关键字创建,也可以使用Arrays.a…

    Java 2023年5月26日
    00
  • Java可视化之实现文本的加密和解密

    Java可视化之实现文本的加密和解密 简介 本文主要介绍如何通过Java可视化界面实现文本的加密和解密功能。具体实现过程采用Java的Swing组件和AES加密算法。 环境 JDK 1.8或以上版本 Eclipse开发环境 实现步骤 步骤1 – 创建Java项目 首先在Eclipse中创建一个Java项目,用于实现加密和解密功能。可以根据自己的习惯和实际需求…

    Java 2023年5月26日
    00
  • Visual Studio Code上添加小程序自动补全插件的操作方法

    操作 Visual Studio Code 上添加小程序自动补全插件的具体步骤如下: 1. 打开 Visual Studio Code 首先,打开你的 Visual Studio Code 编辑器。 2. 打开扩展面板 点击左侧菜单栏最后一个图标,打开 Visual Studio Code 的扩展面板,这里可以搜索并将插件安装到编辑器中。 3. 搜索插件 在…

    Java 2023年5月23日
    00
  • 使用Java Minio搭建自己的文件系统详解

    使用 Java Minio 搭建自己的文件系统 本文将为您详细介绍如何使用 Java Minio 搭建自己的文件系统,让您轻松实现对象存储和文件管理。 什么是Java Minio? Java Minio 是 Minio 这个开源对象存储服务的 Java 版本的 SDK。它提供了对于 Minio 这个云存储的 Java 编程式接口,方便 Java 开发者使用和…

    Java 2023年5月20日
    00
  • tomcat单机多实例的实现

    Tomcat单机多实例的实现是在一台物理服务器上配置多个Tomcat实例,每个实例可以有自己的配置文件、发布目录和端口号,以实现对 Web 应用的快速部署和管理。 下面是实现多实例的详细步骤: 1. 安装 Tomcat 首先需要安装Tomcat,可以到官网下载最新版本,并按照提示进行安装,安装过程很简单,不再赘述。 2. 创建实例目录 在 Tomcat 安装…

    Java 2023年6月2日
    00
  • Java设计模式之java外观模式详解

    Java外观模式是一种结构型设计模式,它可以为复杂的子系统提供一个简单的接口。通过使用外观模式,我们可以将整个子系统的复杂性隐藏在一个简单的接口后面,让客户端只需要与这个简单的接口进行交互,不需要关心具体实现细节。 外观模式的使用场景 外观模式在以下情况下可以得到应用: 当一个复杂的系统需要被分成多个子系统时,可以使用外观模式对外提供一个简单的接口,以隐藏子…

    Java 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部