【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final )(二)

简介: 【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final )(二)

3 . 示例代码 :



① 原型模式深拷贝示例 : 深拷贝与浅拷贝只是在 clone 方法中表现不同 , 其它代码一致 ; 在 clone 方法中需要针对引用类型进行克隆 ;


package kim.hsl.design.prototype.deepcopy;
import java.util.Vector;
/**
 * 浅拷贝示例
 */
public class Student implements Cloneable {
    private String name;
    private int age;
    //该类在拷贝时 , 如果使用浅拷贝 , 只是将地址拷贝走了 , 两个对象实际上用的是同一个对象
    private Vector<String> courses = new Vector<>();
    public Student() {
        System.out.println("调用 Student 默认构造函数");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Vector<String> getCourses() {
        return courses;
    }
    public void setCourses(Vector<String> course) {
        this.courses = course;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", course=" + courses +
                '}';
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("调用 Student clone 方法");
        //1 . 首先拷贝一个基本对象
        Student student = (Student) super.clone();
        //2 . 将引用类型的对象单独克隆赋值
        student.courses = (Vector<String>) this.courses.clone();
        //3 . 返回创建的新的对象
        return student;
    }
}




② 测试代码 :


package kim.hsl.design.prototype.deepcopy;
public class Main {
    public static void main(String[] args) {
        try {
            //测试使用 clone 方法实现的原型模式 , 使用原型模式创建 2 个对象
            Student newStudent = new Student();
            // 1 . 使用 clone 方法创建对象1
            Student student = (Student) newStudent.clone();
            student.setName("Tom");
            student.setAge(10);
            student.getCourses().add("数学");
            // 2 . 使用 clone 方法创建对象2
            Student student2 = (Student) newStudent.clone();
            student2.setName("Jerry");
            student2.setAge(18);
            student2.getCourses().add("语文");
            System.out.println("student : " + student + "\nstudent2 : " + student2);
        } catch (CloneNotSupportedException e) {
            //捕获 clone 方法可能产生的异常
            e.printStackTrace();
        }
    }
}


③ 运行结果 : 原型模式的两个实例对象的互不干扰 ;



调用 Student 默认构造函数
调用 Student clone 方法
调用 Student clone 方法
student : Student{name='Tom', age=10, course=[数学]}
student2 : Student{name='Jerry', age=18, course=[语文]}




IV . 原型模式 与 单例


1 . 原型模式 与 单例模式 :



① 原型模式 : 原型模式的核心是不调用构造函数 , 使用 clone 方法在内存中克隆对象 ;


② 单例模式 : 单例模式的核心是私有化构造函数 , 控制外部用户 , 不能随意调用构造函数创建对象 ;



2 . Cloneable 破坏了单例模式 : 此处二者就出现了矛盾 , 如果单例类 , 实现了 Cloneable 接口 , 那么该类就可以调用 clone 方法创建另外的实例对象 , 因此破坏了单例模式 ;



3 . 解决方案 :


① 不实现 Cloneable 接口 : 单例模式中不要实现 Cloneable 接口 , 不提供内存拷贝功能 ;


② clone 中调用单例 : 如果必须实现 Cloneable 接口 , 那么在重写的 clone 方法中 , 调用获取单例类的方法 , 不要进行内存对象拷贝创建新的实例对象 ;




V . 原型模式 中的 final 关键字 ( 禁止出现 )


1 . final 作用 : final 用于修饰常量 , 被 final 修饰的变量无法重新赋值 ;



2 . Cloneable 实现类成员不要使用 final : 在原型模式的类中 , 实现了 Cloneable 接口 , 重写了 clone 方法 , 其类对象的成员不能被 final 修饰 , 否则无法重新赋值 ;


目录
相关文章
|
1月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
61 0
|
1月前
|
设计模式 安全 Java
【设计模式】原型模式
【设计模式】原型模式
|
1月前
|
设计模式 缓存 安全
单例设计模式的优缺点
单例设计模式的优缺点
32 0
|
1月前
|
设计模式 XML 存储
关于 ABAP 单例设计模式的一个冷门知识点
关于 ABAP 单例设计模式的一个冷门知识点
22 0
|
1月前
|
设计模式 安全 Java
【设计模式】2、设计模式分类和单例设计模式
【设计模式】2、设计模式分类和单例设计模式
25 0
|
1月前
|
设计模式 Java
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
28 2
|
27天前
|
设计模式 安全 Java
在Java中即指单例设计模式
在Java中即指单例设计模式
18 0
|
14天前
|
设计模式 Java
小谈设计模式(10)—原型模式
小谈设计模式(10)—原型模式
|
1月前
|
设计模式 Java
设计模式之原型模式
设计模式之原型模式
|
18天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
19 0