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


    定义

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

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

    浅克隆和深克隆的区别

    • 浅克隆:能复制变量,如果对象内还有对象,则只能复制对象的地址
    • 深克隆:能复制变量,也能复制当前对象的内部对象
  • 相关阅读:
    swift
    swift
    c# 根据自定义Attribute排序
    asp.net 导出excel
    算法时间复杂度的计算 [整理]
    再谈javascript原型继承
    深入学习JavaScript: apply 方法 详解(转)——非常好
    Chapter 6 : Control Statements : Looping
    Chapter 6 : Applications of Definite Integrals
    朋友圈仅三天可见?怎么破?
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/11453144.html
Copyright © 2020-2023  润新知