原型模式的用法

news2024/11/26 14:23:51

文章目录

  • 一、原型模式的用法
    • 1.1 介绍
    • 1.2 结构
    • 1.3 原型模式类图
    • 1.4 实现
      • 1.4.1 克隆的分类
      • 1.4.2 代码
    • 1.5 "三好学生"奖状案例
      • 1.5.1 "三好学生"奖状类图
      • 1.5.2 代码
    • 1.6 深、浅克隆的区分
      • 1.6.1 浅克隆
      • 1.6.2 深克隆

一、原型模式的用法

1.1 介绍

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

1.2 结构

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

1.3 原型模式类图

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

在这里插入图片描述

1.4 实现

1.4.1 克隆的分类

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

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

1.4.2 代码

/**
 * 具体原型类: 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 "三好学生"奖状案例

1.5.1 "三好学生"奖状类图

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

在这里插入图片描述

1.5.2 代码

/**
 * 学生实体类: 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 深、浅克隆的区分

1.6.1 浅克隆

创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。stu对象和stu1对象是同一个对象,就会产生将stu1对象中name属性值改为“李四”,两个Citation(奖状)对象中显示的都是李四。这就是浅克隆的效果,对具体原型类(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 深克隆

创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。深克隆需要使用对象流来实现。

注意:Citation类和Student类必须实现Serializable接口,否则会抛NotSerializableException异常。

/**
 * 学生实体类: 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();
    }
}

记录每一个学习瞬间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/616014.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STL(结)

STL&#xff08;结&#xff09; map存储结构基本操作equal_range遍历方式 插入 multimapsetunordered_mapmap和无序map的异同mapunordered_map map 存储结构 map容器的底层存储是一个红黑树&#xff0c;遍历方式都是按照中序遍历的方式进行的。 int main() {std::map<int…

数组降维

写一个函数&#xff0c;打印数组内的内容&#xff0c;代码为&#xff1a; #include<stdio.h>void show_arr(int arr[], int num) {int i 0;for (i 0; i < num; i){printf("%d ", arr[i]);}printf("\n"); } int main() {int arr[] { 1,2,3,4,5…

Servlet Cookie基本概念和使用方法

目录 Cookie 介绍 Cookie 主要有两种类型&#xff1a;会话 Cookie 和持久 Cookie。 Cookie使用步骤 使用Servlet和Cookie实现客户端存储的登录功能示例&#xff1a; LoginServlet类 index.jsp 删除Cookie 浏览器中查看Cookie的方法 Cookie 介绍 Cookie 是一种在网站和…

win10下载安装mysql8.0版本

打开官网下载&#xff1a;https://dev.mysql.com/downloads/mysql/ 下载完成后解压&#xff0c;这里我是直接放在C盘 然后打开mysql目录文件夹新建my.ini文件,my.ini文件内容如下&#xff0c;需要修改两个地方&#xff0c;其中datadir你自己的mysql的安装目录&#xff0c;data…

如何在线压缩png图片?png压缩图片大小的方法介绍

压缩PNG图片大小的优点 随着数字化时代的发展&#xff0c;PNG格式已成为一种常见的图片格式。然而&#xff0c;由于高分辨率、高色深等原因&#xff0c;PNG图片通常具有较大的文件体积&#xff0c;导致在传输、存储和网页加载等方面会产生不必要的负担。因此&#xff0c;对于需…

ai绘画生成古风场景怎么弄?告诉你怎么ai绘画

随着人工智能技术的不断发展&#xff0c;ai绘画已经成为一个令人着迷的领域。一些软件利用深度学习算法和生成对抗网络等技术&#xff0c;能够帮助艺术家和爱好者创造出令人惊叹的艺术作品。今天我就来跟大家分享一下如何一键ai绘画&#xff0c;感兴趣的朋友就跟我一起看下去吧…

《文体用品与科技》期刊简介及投稿要求

《文体用品与科技》期刊简介&#xff1a; 主管单位&#xff1a;中国轻工业联合会 主办单位&#xff1a;中国文教体育用品协会、全国文教体育用品信息中心、北京市文教体育用品研究所 国际刊号&#xff1a; ISSN1006-8902 国内刊号;CN:11-3762/TS 邮发代号;82-21932 发表周…

DDR跑不到速率后续来了,相邻层串扰深度分析!

高速先生成员&#xff1a;黄刚 就在刚刚&#xff0c;雷豹把他对叠层的调整方式和改善后的仿真结果给师傅Chris看完后&#xff0c;Chris给雷豹点了个大大的赞&#xff0c;因为优化的方式其实不需要大改DDR的走线&#xff0c;只需要把相邻层的信号最大限度的拉开&#xff0c;同时…

如何定位分析视频异常画面

背景 视频典型画面不正常主要包含画面卡顿、画面模糊、画面不显示、画面花屏这 4 类问题。本文主要介绍的是画面花屏的情况&#xff0c;这里的画面花屏包含了花屏、闪屏、绿屏、黑屏。视频花屏是多媒体工程师最常见的问题之一&#xff0c;也是最棘手的问题之一&#xff0c;笔者…

有什么可靠稳定的微信管理系统?

微信管理系统是什么 微信管理系统从字面上来说可以理解为微信的管理和营销系统。通俗一点来说就是利用微信与管理营销相结合的一种新型办公方式。 不用下载任何软件&#xff0c;不用多部手机&#xff0c;对手机没有任何型号要求&#xff0c;不需要刷机、越狱&#xff0c;不需…

政务APP小程序开发 畅享全新政府办事体验

现在很多政府机构打着便民的口号&#xff0c;但其实生活中很多时候去政府机构办事都很费时间&#xff0c;周末节假日不上班没法办理&#xff0c;工作日去人多排长队不说&#xff0c;往往排到自己了又因为资料不全、手续不齐&#xff0c;无法证明自己等奇葩原因不得不一次次被拒…

boost 搜索引擎

boost搜索引擎 01 项目演示 done 02 讲解思路 03 项目背景 公司&#xff1a;百度、搜狗、360搜索、头条新闻客户端 - 我们自己实现是不可能的&#xff01; 站内搜索&#xff1a;搜索的数据更垂直&#xff0c;数据量其实更小 boost的官网是没有站内搜索的&#xff0c;需要…

家乡乐山美食网站系统(含源码+数据库)

1.需求分析 将进行家乡乐山美食网站的需求分析。需求分析是系统开发过程中的一项重要工作&#xff0c;它是对用户需求进行深入研究和分析&#xff0c;明确系统的功能、性能、界面等方面的需求&#xff0c;为后续的设计和开发提供依据。 首先&#xff0c;需要明确该网站的主要目…

成为一个优秀的测试工程师需要具备哪些知识和经验?

目录 前言&#xff1a;  1、我们先来讲第一点&#xff0c;由单纯的测试变成项目质量保证工作 2、持续集成探索和自动化测试技术研究 3、测试相关工具的开发 总结忠告 前言&#xff1a;  本人7年测试经验&#xff0c;在学测试之前对电脑的认知也就只限于上个网&#xff0c;…

狂野java前置课程-线程池的基本使用

回顾 什么是线程&#xff0c;什么是进程&#xff1f; 进程&#xff1a;是一个应用程序&#xff0c;里面包含很多线程线程&#xff1a;进程执行的基本单元 java实现线程的几种方式 继承Thread类实现Runable接口 线程的生命周期 执行线程会出现的问题 一个线程只能执行一个…

【专为苛刻的数据环境而构建】上海道宁为您带来世界上先进的矢量原生、时间序列和实时分析数据库——kdb系列产品

kdb是高效的矢量原生 时间序列和实时分析数据库 专为高性能矢量 数据驱动的应用程序而构建 以加速云端、数据仓库和 数据湖中的 AI 和 ML 工具 从而更快、更高效地 制定业务决策 使用数据时间库加速数据 分析和生成 AI 管道 以降低成本 提高性能并提高效率 开发商介绍…

移动端图形API通讲(一)--从Gles、Vulkan到Metal

转载请注明&#xff0c;来自leonnwei的csdn blog 引言 一直想整理下关于移动端图形编程API的文档。图形API为何重要&#xff1f;如果说图形编程的内功是计算机图形学的诸原理和算法&#xff0c;那么外功就是实实在在的硬件API。不能精通API的使用&#xff0c;就无法把渲染特性合…

新来个技术总监,把限流实现的那叫一个优雅,佩服!

在电商高并发场景下&#xff0c;我们经常会使用一些常用方法&#xff0c;去应对流量高峰&#xff0c;比如限流、熔断、降级&#xff0c;今天我们聊聊限流。 什么是限流呢&#xff1f;限流是限制到达系统的并发请求数量&#xff0c;保证系统能够正常响应部分用户请求&#xff0…

人脸比对指标 -- 人脸相似度

目前市面上既有OpenCV等开源算法库&#xff0c;很多芯片厂商的产品也自带简单算法&#xff0c;同时专业算法大厂也会开放相关技术&#xff0c;如提供免费、离线人脸识别SDK的虹软视觉开放平台等。对于开发者而言&#xff0c;面对多种算法&#xff0c;如何进判断算法性能至关重要…

Vue初始化项目加载逻辑

Vue初始化项目加载逻辑 项目创建 我们只需要创建项目即可&#xff0c;剩余的依赖都没必要安装 我们先来看main.js,咱们加了一行备注 import Vue from vue import App from ./App.vue import router from ./router import store from ./storeVue.config.productionTip fals…