110.【十万字带你深入学习23种设计模式】(八)

简介: 110.【十万字带你深入学习23种设计模式】

2.原型模式

(1).概述

用一个创建的实列作为原型,通过复制该原型对象来创建一个和原型都相同的新对象。

(2).结构

原型模式包含如下角色:

  • 抽象原型类: 规定了具体原型对象必须实现的Clone()方法。JDK帮我们做了
  • 具体原型类: 实现抽象原型类的cone()方法,它是可以被复制的对象
  • 访问类: 使用具体原型类中的clone()方法来复制新的对象。

(3).实现

原型模式的克隆分为浅克隆和深克隆

浅克隆: 浅克隆:对当前对象进行克隆,并克隆该对象所包含的8种基本数据类型和String类型属性(拷贝一份该对象并重新分配内存,即产生了新的对象);但如果被克隆的对象中包含除8中数据类型和String类型外的其他类型的属性,浅克隆并不会克隆这些属性(即不会为这些属性分配内存,而是引用原来对象中的属性,而不拷贝对象包含的引用指向的对象。会指向原有对象的地址,内存地址一样

深克隆: 深克隆:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。不再指向原有对象的地址

Java中的Object类中提供了 clone() 方法来实现浅克隆Cloneable接口是上面的类图中的抽象原型类,而实现了cloneable接口的子实现类就是具体的原型类

具体原型类: 这里我们继承coneable接口重写clone()方法实现克隆

package com.jsxs.pattern.prototype.demo;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:23
 * @PackageName:com.jsxs.pattern.prototype.demo
 * @ClassName: Realizetype
 * @Description: TODO
 * @Version 1.0
 */
public class Realizetype implements Cloneable{
    public Realizetype(){
        System.out.println("具体的原型对象被创建了");
    }
    // 1.重写方法
    @Override
    public Realizetype clone() throws CloneNotSupportedException {
        System.out.println("具体原型复制成功!!!");
        return (Realizetype)super.clone();
    }
}

访问类

package com.jsxs.pattern.prototype.demo;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:33
 * @PackageName:com.jsxs.pattern.prototype.demo
 * @ClassName: Client
 * @Description: TODO
 * @Version 1.0
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 1.创建一个原型类对象
        Realizetype realizetype = new Realizetype();  //  ->利用无参的构造方法去创建对象
        //2.调用Realizetype类中我们重写的clone()方法进行对象的克隆
        Realizetype clone = realizetype.clone();
        System.out.println("原型对象和克隆的对象是否是同一个对象 "+(realizetype==clone));
    }
}
• 1

(4).案列

用原型模式生成 "三好学生"奖状

同一学校的"三号学生"奖状除了获奖人姓名不同,其他都相同,可以使用原型模式复制多个:"三好学生"奖状出来,然后再修改奖状上的名字即可。

具体原型类: 这里我们继承coneable接口重写clone()方法实现克隆

package com.jsxs.pattern.prototype.demo2;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:52
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Citation
 * @Description: TODO
 * @Version 1.0
 */
public class Citation implements Cloneable{
    // 基本属性
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    // 重写clone方法
    @Override
    public Citation clone() throws CloneNotSupportedException {
        return (Citation)super.clone();
    }
    public void show(){
        System.out.println(name+"获得奖状一张!!");
    }
}

访问类

package com.jsxs.pattern.prototype.demo2;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:54
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Client
 * @Description: TODO
 * @Version 1.0
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 1.原型对象的创建
        Citation citation = new Citation();
        citation.setName("李明-原型对象");
        // 2.克隆对象
        Citation clone = citation.clone();
        clone.setName("吉士-克隆对象");
    citation.show();
        clone.show();
        System.out.println(citation==clone);
    }
}

(5).使用场景
  • 对象的创建非常复杂,可以使用原型模式快捷的创建对象
  • 性能和安全要求比较高
(6).扩展(深克隆)

将上面的"三好学生"奖状的案列中的name属性更改为Student类型的属性。

浅克隆

引用对象类

package com.jsxs.pattern.prototype.demo2;
/**
 * @Author Jsxs
 * @Date 2023/4/18 14:22
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Student
 * @Description: TODO
 * @Version 1.0
 */
public class Student {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

具体原型类

package com.jsxs.pattern.prototype.demo2;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:52
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Citation
 * @Description: TODO
 * @Version 1.0
 */
public class Citation implements Cloneable{
    // 基本属性
    private Student student;
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    // 重写clone方法
    @Override
    public Citation clone() throws CloneNotSupportedException {
        return (Citation)super.clone();
    }
    public void show(){
        System.out.println(student.getName()+"获得奖状一张!!");
    }
}

访问类

package com.jsxs.pattern.prototype.demo2;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:54
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Client
 * @Description: TODO
 * @Version 1.0
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 1.原型对象的创建
        Citation citation = new Citation();
        Student student = new Student();
        student.setName("原型对象-张三");
        citation.setStudent(student);
        // 2.克隆对象
        Citation clone = citation.clone();
        Student student1 = citation.getStudent();
        student1.setName("克隆对象-李四");
        clone.show();
        citation.show();
        System.out.println(student==student1);
    }
}

说明: student和student1的对象是一个对象,就会产生studen1对象的属性会覆盖student的属性的效果。对具体原型类中的引用类型的属性进行引用的复制。这种情况需要使用深克隆,而进行深克隆需要使用对象流

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程

Student引用类-> 序列化

package com.jsxs.pattern.prototype.demo3;
import java.io.Serializable;
/**
 * @Author Jsxs
 * @Date 2023/4/18 14:22
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Student
 * @Description: TODO
 * @Version 1.0
 */
public class Student implements Serializable {  //序列化
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

具体克隆类 -> 序列化

package com.jsxs.pattern.prototype.demo3;
import java.io.Serializable;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:52
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Citation
 * @Description: TODO
 * @Version 1.0
 */
public class Citation implements Serializable {
    // 基本属性
    private Student student;
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public void show(){
        System.out.println(student.getName()+"获得奖状一张!!");
    }
}

访问类

package com.jsxs.pattern.prototype.demo3;
import java.io.*;
/**
 * @Author Jsxs
 * @Date 2023/4/18 13:54
 * @PackageName:com.jsxs.pattern.prototype.demo2
 * @ClassName: Client
 * @Description: TODO
 * @Version 1.0
 */
public class Client{
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        // 1.原型对象的创建
        Citation citation = new Citation();
        Student student = new Student();
        student.setName("原型对象-张三");
        citation.setStudent(student);
        // 2.创建对象输出流对象
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("E:\\加速器\\a.txt"));
        out.writeObject(citation); //将原型对象写入文件中
        out.close();  //关闭资源
        ObjectInputStream ipt = new ObjectInputStream(new FileInputStream("E:\\加速器\\a.txt"));
        Citation citation1 = (Citation)ipt.readObject();
        ipt.close();  //关闭资源
        Student student1 = citation1.getStudent();
        student.setName("克隆对象-李四");
        citation.show();
        citation1.show();
        System.out.println(student==student1);
    }
}

相关文章
|
3月前
|
设计模式 监控 安全
多线程设计模式【多线程上下文设计模式、Guarded Suspension 设计模式、 Latch 设计模式】(二)-全面详解(学习总结---从入门到深化)
多线程设计模式【多线程上下文设计模式、Guarded Suspension 设计模式、 Latch 设计模式】(二)-全面详解(学习总结---从入门到深化)
84 0
|
2月前
|
设计模式 存储 算法
设计模式学习心得之五种创建者模式(2)
设计模式学习心得之五种创建者模式(2)
23 2
|
2月前
|
设计模式 uml
设计模式学习心得之前置知识 UML图看法与六大原则(下)
设计模式学习心得之前置知识 UML图看法与六大原则(下)
18 2
|
2月前
|
设计模式 安全 Java
设计模式学习心得之五种创建者模式(1)
设计模式学习心得之五种创建者模式(1)
19 0
|
2月前
|
设计模式 数据可视化 程序员
设计模式学习心得之前置知识 UML图看法与六大原则(上)
设计模式学习心得之前置知识 UML图看法与六大原则(上)
18 0
|
3月前
|
设计模式 安全 Java
【JAVA学习之路 | 基础篇】单例设计模式
【JAVA学习之路 | 基础篇】单例设计模式
|
3月前
|
设计模式 安全 Java
【设计模式学习】单例模式和工厂模式
【设计模式学习】单例模式和工厂模式
|
3月前
|
设计模式 算法 程序员
Python从入门到精通:2.1.3深入学习面向对象编程——设计模式的学习与实践
Python从入门到精通:2.1.3深入学习面向对象编程——设计模式的学习与实践
|
3月前
|
设计模式 存储 前端开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
|
3月前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式