设计模式学习总结(五)--原型模式

定义

原型模式也是一种创建模式。通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。

原型模式要求对象实现一个可以 “克隆” 自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例。这样一来,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过 new 实例化来创建对象。

优缺点

优点:可以动态地添加产品类而且对整体结构没有影响。

缺点:由于原型模式需要给每一个类都配备一个克隆的方法,这就需要在设计类时通盘考虑。因为在已有类的基础上添加 clon e操作比较困难。

实例

需求:

有一个学校需要维护学生信息,其中学校名称都是固定的,只有学生的姓名需要改变

学生对象定义:

public class Student implements Cloneable {

    /**
     * 学习名称
     */
    private String schoolName;

    /**
     * 学生名称
     */
    private String studentName;


    public String getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

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

    @Override
    public String toString() {
        return "学校名称:" + this.schoolName + "; 学生姓名:" + this.studentName;
    }
}

逻辑实现:

public static void main(String[] args) throws CloneNotSupportedException {
    Student student = new Student();
    student.setSchoolName("浙江大学");
    System.out.println("克隆前  >"+student.toString());
    for (int i = 0; i < 10; i++) {
        Student newStudent = (Student) student.clone();
        newStudent.setStudentName("学生--" + i);
        System.out.println("克隆中  >"+newStudent.toString());
    }
    System.out.println("克隆后  >"+student.toString());

}

控制台输出:

克隆前  >学校名称:浙江大学; 学生姓名:null
克隆中  >学校名称:浙江大学; 学生姓名:学生--0
克隆中  >学校名称:浙江大学; 学生姓名:学生--1
克隆中  >学校名称:浙江大学; 学生姓名:学生--2
克隆中  >学校名称:浙江大学; 学生姓名:学生--3
克隆中  >学校名称:浙江大学; 学生姓名:学生--4
克隆中  >学校名称:浙江大学; 学生姓名:学生--5
克隆中  >学校名称:浙江大学; 学生姓名:学生--6
克隆中  >学校名称:浙江大学; 学生姓名:学生--7
克隆中  >学校名称:浙江大学; 学生姓名:学生--8
克隆中  >学校名称:浙江大学; 学生姓名:学生--9
克隆后  >学校名称:浙江大学; 学生姓名:null

注意

以上代码有两个隐藏的风险:

  1. 上面的克隆只是浅克隆,深克隆需要自己实现克隆方法
  2. 反序列化时会重新生成一个对象,而不是之前的对象

那么要怎么解决呢,只需要我们自己实现下 clone 方法

@Override
protected Student clone() throws CloneNotSupportedException {
    Student student = (Student) super.clone();
    // 克隆其他对象属性
    return student;
}

浅克隆和深克隆的区别

  • 浅克隆:能复制变量,如果对象内还有对象,则只能复制对象的地址
  • 深克隆:能复制变量,也能复制当前对象的内部对象
原文地址:https://www.cnblogs.com/markLogZhu/p/11453144.html