Usage of Prototype Pattern

1. The usage of prototype mode

1.1 Introduction

Use an already created instance as a prototype, and create a new object identical to the prototype object by copying the prototype object .

1.2 Structure

  • Abstract prototype class : specifies the clone() method that the concrete prototype object must implement.
  • Concrete prototype class : implement the clone() method of the abstract prototype class, which is an object that can be copied.
  • Access class : use the clone() method in the concrete prototype class to copy the new object.

1.3 Prototype pattern class diagram

The Object class in Java provides clone()methods to implement shallow cloning . The Cloneable interface is an abstract prototype class in the class diagram, and the sub-implementation class that implements the Cloneable interface is a concrete prototype class.

insert image description here

1.4 Implementation

1.4.1 Classification of clones

Prototype mode cloning is divided into shallow cloning and deep cloning.

Shallow clone: ​​create a new object, the attributes of the new object are exactly the same as the original object, and for non-basic type attributes, it still points to the memory address of the object pointed to by the original attribute.

Deep clone: ​​When a new object is created, other objects referenced in the attribute will also be cloned and no longer point to the original object address.

1.4.2 Code

/**
 * 具体原型类: Realizetype
 */
public class Realizetype implements Cloneable{
    
    
    // 无参构造函数,创建对象时运行里面的代码
    public Realizetype() {
    
    
        System.out.println("具体的原型对象创建完成");
    }
    @Override
    public Realizetype clone() throws CloneNotSupportedException {
    
    
        System.out.println("具体原型复制成功");
        // Object类中提供了clone()方法来实现浅克隆,强转为Realizetype
        return (Realizetype) super.clone();
    }
}

/**
 * 访问类: client
 */
public class client{
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        // 创建一个原型类的对象
        Realizetype realizetype = new Realizetype();
        // 调用Realizetype类中的clone方法进行对象的克隆
        Realizetype clone = realizetype.clone();
        System.out.println("原型对象和克隆出来的对象是否为一个对象:" + (realizetype == clone));// false
    }
}

1.5 Cases of "Three Good Students" Award

1.5.1 Class Diagram of "Three Good Students" Award

The "Three Good Students" certificates of the same school are the same except for the names of the winners. You can use the prototype mode to copy multiple "Three Good Students" certificates, and then modify the names on the certificates.

insert image description here

1.5.2 Code

/**
 * 学生实体类: Student
 */
public class Student {
    
    
    // 学生姓名
    private String name;

    public Student() {
    
    
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
    
    
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public String toString() {
    
    
        return "Student{name = " + name + "}";
    }
}

/**
 * 具体原型类: Citation
 */
public class Citation implements Cloneable {
    
    
    private Student stu;

    public Student getStudent(){
    
    
        return stu;
    }

    public void setStudent(Student stu){
    
    
        this.stu = stu;
    }

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

    public void show() {
    
    
        System.out.println(stu.getName() + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

/**
 * 访问类: CitaionTest
 */
public class CitaionTest {
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        // 创建原型对象
        Citation citation = new Citation();
        // 创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStudent(stu);

        // 克隆奖状对象
        Citation citation1 = citation.clone();
        // 避免浅克隆的问题,重新声明一个对象
        Student stu1 = new Student();
        stu1.setName("李四");
        citation1.setStudent(stu1);

        // 调用show方法展示
        citation.show();
        citation1.show();
    }
}

1.6 Distinguishing between deep and shallow clones

1.6.1 Shallow clone

Create a new object, the attributes of the new object are exactly the same as the original object , and for non-basic type attributes, it still points to the memory address of the object pointed to by the original attribute. The stu object and the stu1 object are the same object, so the value of the name attribute in the stu1 object will be changed to "Li Si", and the two Citation (certificate) objects will display Li Si. This is the effect of shallow cloning, copying the attributes of the reference type in the concrete prototype class (Citation) .

/**
 * 学生实体类: Student
 */
public class Student {
    
    
    // 学生姓名
    private String name;

    public Student() {
    
    
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
    
    
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public String toString() {
    
    
        return "Student{name = " + name + "}";
    }
}

/**
 * 具体原型类: Citation
 */
public class Citation implements Cloneable {
    
    
    private Student stu;

    public Student getStudent(){
    
    
        return stu;
    }

    public void setStudent(Student stu){
    
    
        this.stu = stu;
    }

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

    public void show() {
    
    
        System.out.println(stu.getName() + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

/**
 * 访问类: CitaionTest
 */
public class CitaionTest {
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        // 创建原型对象
        Citation citation = new Citation();
        // 创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStudent(stu);
        // 克隆奖状对象
        Citation citation1 = citation.clone();
        Student stu1 = citation1.getStudent();
        stu1.setName("李四");

        //3,调用show方法展示
        citation.show();//李四同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!
        citation1.show();//李四同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!
    }
}

1.6.2 Deep Cloning

When a new object is created, other objects referenced in the attribute will also be cloned and no longer point to the original object address. Deep cloning needs to be implemented using object streams .

Note: The Citation class and the Student class must implement the Serializable interface, otherwise a NotSerializableException will be thrown.

/**
 * 学生实体类: Student
 */
public class Student implements Serializable {
    
    
    // 学生姓名
    private String name;

    public Student() {
    
    
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
    
    
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public String toString() {
    
    
        return "Student{name = " + name + "}";
    }
}

/**
 * 具体原型类: Citation
 */
public class Citation implements Cloneable,Serializable {
    
    
    private Student stu;

    public Student getStudent(){
    
    
        return stu;
    }

    public void setStudent(Student stu){
    
    
        this.stu = stu;
    }

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

    public void show() {
    
    
        System.out.println(stu.getName() + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

/**
 * 访问类: CitaionTest
 */
public class CitaionTest {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 创建原型对象
        Citation citation = new Citation();
        // 创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStu(stu);

        // 创建对象输出流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D://a.txt"));
        // 写对象
        oos.writeObject(citation);
        // 释放资源
        oos.close();

        // 创建对象输入流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D://a.txt"));
        // 读取对象
        Citation citation1 = (Citation) ois.readObject();
        // 释放资源
        ois.close();
        Student stu1 = citation1.getStu();
        stu1.setName("李四");

        citation.show();
        citation1.show();
    }
}

记录每一个学习瞬间

Guess you like

Origin blog.csdn.net/qq_51601665/article/details/131071684
Recommended