设计模式8——原型模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。

原型模式(Prototype)

目录

一、概述

二、优点

三、使用步骤

四、举例(深复制)


一、概述

1、用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象;
2、可以从一个对象再创建另外一个可定制的对象,而且不需要知道任何的细节;
3、不用重新初始化对象,而是动态地获得对象运行时得状态。

1.1、主要的角色就一种:

  • 待克隆的对象:也就是需要频繁被复制的对象,我们采用克隆的思想去复制他。

或许会有疑问,这个模式不就是复制实例对象吗?着我手动代码就复制了,有必要专门讨论吗?和一般一行一行代码复制不一样,这个的理论是希望他能直接在内存里就复制过去,而不是我们再创建一片空间,然后把对象属性一个一个复制过去。就此我们将对比两种方式、如下图

1.2、  一般复制和原型模式的对比:

1.3、通过技术实现的角度看,UML图如下:

二、优点

  • 提高了性能、也减少了重复代码

三、使用步骤

  1. 如果有某个类需要同时创建大量的实例,并且这个类的实例大都相似,那么就可以考虑使用原型模式;
  2. 实现原型模式对于不同语言有不同的方式,但应该提供一个接口,用来克隆对象实例。

四、举例(深复制)

假设张三要写两份简历,简历里有姓名、性别、年龄、以及工作经历,其中工作经历是一个引用对象;因为某些原因,两份简历,其中年龄不一样(一个是25岁,一个是28岁)、工作经历不一样(一个是在度百工作经历,一个是讯腾工作经历),其他的都一样。

4.1、分析步骤:

1、分析上述问题:

  • 我们发现完全填写好一份简历比较麻烦,且此简历都属于同一个人,只是某些项有不同,此时我们可以考虑原型模式;
  • 对于原型模式,实际实现时都是去实现克隆接口,此接口应当可以完成对实例的完整复制;
  • 另外本例有一个引用对象——工作经历,一般情况下复制是简历里变量的值,也就是工作经历引用地址,所以会导致多个简历实例对象里的工作经历变量指向同一个工作经历实例对象,这肯定是有问题的,还需要另外的处理,就是让工作经历类也可以克隆,也即深复制。这样每次克隆或复制简历对象时,也克隆工作经历,让新复制的简历里的工作经历变量也指向新复制的实例。同理,当有多个引用对象时,应当都应用原型模式,使其可以克隆或复制。

2、针对问题的设计要素:

  • 简历类
  • 工作经历类

都要实现克隆或复制。

4.2、uml图如下:

4.3、Java实现代码如下(建议你在本地试一下,加深印象):

(对于Java实现原型模式,需要实现Cloneable接口,然后再写clone方法)

工作经历类:

public class WorkExperience implements Cloneable {
    private String timeArea; //工作时间

    public String getTimeArea() {
        return timeArea;
    }

    public void setTimeArea(String timeArea) {
        this.timeArea = timeArea;
    }

    private String company; //工作公司名称

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public WorkExperience clone() { //实现克隆接口
        WorkExperience workExperience = null;
        try {
            workExperience = (WorkExperience) super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println("Clone异常");
        }
        return workExperience;
    }
}

简历类:

public class Resume implements Cloneable{
    private String name; //姓名
    private String sex; //性别
    private String age; //年龄
    private WorkExperience workExperience; //工作经历类

    public Resume(String name) {
        this.name = name;
        this.workExperience = new WorkExperience();
    }

    public void setPersonalInfo(String sex, String age) {
        this.sex = sex;
        this.age = age;
    }

    public void setWorkExperience(String timeArea, String company) {
        this.workExperience.setTimeArea(timeArea);
        this.workExperience.setCompany(company);
    }

    public void display() { //展示简历
        System.out.println(this.name + " " + this.sex + " " + this.age);
        System.out.println("工作经历:" + this.workExperience.getTimeArea() + " " + this.workExperience.getCompany());
    }

    public Resume clone(){  //实现克隆接口
        Resume resume = null;
        try {
            resume = (Resume) super.clone();
            resume.workExperience = this.workExperience.clone();  //调用对引用对象工作经历的克隆接口,将新复制的工作经历实例对象复制给本对象的成员变量,从而最终能够实现深复制
        } catch (CloneNotSupportedException e) {
            System.out.println("Clone异常");
        }
        return resume;
    }
}

 主程序(发起请求的类):

public class Main {
    public static void main(String[] args) {
        //第一份简历
        Resume resume1 = new Resume("张三");
        resume1.setPersonalInfo("man", "25");
        resume1.setWorkExperience("2015-2018", "度百");

        //第二份简历
        Resume resume2 = resume1.clone(); //复制第一份简历,然后再第一份简历上做简单修改可以得到第二份简历
        resume2.setPersonalInfo("man", "28");
        resume2.setWorkExperience("2018-2021", "讯腾");

        System.out.println("第一份简历:");
        resume1.display(); //展示简历1
        System.out.println("第二份简历:");
        resume2.display(); //展示简历2
    }
}

这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。

如果觉得本文还不错,就请点个赞吧!如果有建议,也请评论指教和讨论!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MiniCPM-Llama3-V-2_5-int4

MiniCPM-Llama3-V-2_5-int4大模型部署使用环境: python3.8cuda11.8其它要求,按照安装文档要求下载即可 我是在算力平台用4090跑的, GPU 显存(8GB)可以部署推理 int4 量化版本,如果推理非量化版本需要更高显…

开视频号小店要花哪些钱?这些费用大家要知道

大家好,我是喷火龙。 目前,视频号小店从推出到现在已经快两年的时间了,视频号小店虽然门槛高,但是单价也高,利润也高,市场环境也好,算是一个不错的项目。 接下来给大家讲讲开视频号小店要花哪…

推荐五个线上兼职,在家也能轻松日入百元,适合上班族和全职宝妈

在这个瞬息万变的时代,你是否也曾考虑过在繁忙的工作之外,寻找一份兼职副业来补贴家用,同时保持生活的多样性?别急,现在就让我为你揭秘五个可靠的日结线上兼职岗位,助你轻松迈向财务自由之路! 一…

VBA批量合并带有图片、表格与文本框的Word

本文介绍基于VBA语言,对大量含有图片、文本框与表格的Word文档加以批量自动合并,并在每一次合并时添加分页符的方法。 在我们之前的文章基于Python中docx与docxcompose批量合并多个Word文档文件并逐一添加分页符(https://blog.csdn.net/zhebu…

iBarcoder for Mac v3.15.1中文激活版:让条形码生成变得如此简单

在现代社会,条形码无处不在,从超市商品到物流包裹,都离不开它的身影。iBarcoder for Mac作为一款简单易用的条形码生成软件,让条形码的生成变得如此简单。 iBarcoder for Mac v3.15.1中文激活版下载 无论你是需要为商品添加条形码…

信息安全等级保护测评: 登陆日志

文章目录 引言I 登录日志表结构设计II 日志处理2.1 封装日志入库2.2 收集登陆信息2.3 查询接口引言 等保测评是信息安全等级保护测评的简称,是对信息和信息载体按照重要性等级分级别进行检测、评估的过程。 背景:近期AIS监控平台(网页版)等保测评,发现没有登陆日志,现要…

【高时效通路】

一 高时效通路 1.1 pathchdumper 实时数据拉取、实时数据处理、5分钟微批dump来加速时效性,具体来说: 实时数据拉取(Fetcher):基于Databus Fetcher基建,直接对接F0层实时拉取最新数据,保证该…

微服务架构-链式微服务设计模式

微服务架构-链式微服务设计模式 链式微服务设计模式(Chain Microservice Pattern)是一种微服务架构中的设计模式,它强调将一系列的服务按照特定的业务逻辑顺序串联起来,形成一个服务链。每个服务在链中负责完成特定的业务功能&am…

基于JSP/Servlet校园二手交易平台(二)

目录 2 开发技术及开发环境 2.1 Java语言简介 2.2 J2EE技术介绍 2.3 Servlet/JSP技术 2.4 MVC 简介 2.5 Struts 技术 2.6 Hibernate 技术 2.6.1 应用程序的分层体系结构 2.6.2 Hibernate的应用及API简介 2.7 开发环境及环境配置 2.7.1 Java/JSP系统环境 2.7.2 JSP环…

uniapp 对接 微信App/支付宝App 支付

相关文档:uni.requestPayment(OBJECT) | uni-app官网 示例代码: import qs from qsasync aliPay(){const { provider } await uni.getProvider({ service:payment })if(provider.includes(alipay)){uni.request({url:后端接口地址,data:{ //传参 },suc…

Rabbitmq 搭建使用案例 [附源码]

Rabbitmq 搭建使用案例 文章目录 RabbitMQ搭建docker 代码golang生产者消费者 可视化消费进度 RabbitMQ搭建 docker docker run -d --hostname rabbitmq --name rabbitmq -e RABBITMQ_DEFAULT_USERadmin -e RABBITMQ_DEFAULT_PASSadmin -e RABBITMQ_DEFAULT_VHOSTmy_vhost -e…

分类预测 | Matlab实现ZOA-SVM斑马算法优化支持向量机的多变量输入数据分类预测

分类预测 | Matlab实现ZOA-SVM斑马算法优化支持向量机的多变量输入数据分类预测 目录 分类预测 | Matlab实现ZOA-SVM斑马算法优化支持向量机的多变量输入数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现ZOA-SVM斑马算法优化支持向量机的多变量输…

5. C++网络编程-UDP协议的实现

UDP是无连接的。 UDP Server网络编程基本步骤 创建socket,指定使用UDP协议将socket与地址和端口绑定使用recv/send接收/发送数据 由于UDP是无连接的,直接侦听就行使用close关闭连接 这个UDP接收数据的时候用的API是recvfrom,发送数据是sendto 客户端 …

IS-IS链路状态数据库

原理概述 一个OSPF链路状态数据库是若干条LSA的集合。与此相似,一个IS-IS链路状态数据库是由若干条LSP的集合。与OSPF链路状态数据库不同,IS-IS链路状态数据库有Level-1和Level-2之分。 在IS-IS协议中,每一条LSA都有一条剩余生存时间、一个…

Behind the Code:Polkadot 如何重塑 Web3 未来

2024 年 5 月 17 日 Polkadot 生态 Behind the Code 第二季第一集 《创造 Web3 的未来》正式上线。第一集深入探讨了 Polkadot 和 Web3 技术在解决数字身份、数据所有权和去中心化治理方面的巨大潜力。 🔍 查看完整视频: https://youtu.be/_gP-M5nUidc?…

Docker安装OnlyOffice

工作需要,多人在线编辑同一文档,找了一圈发现onlyoffice满足需求,于是使用docker安装了社区版本。下面记录下安装过程。 Onlyoffice 是什么? Onlyoffice 是一个多端协同的 Office 办公套件,相当于微软的 Office365 全…

MySQL多表关联查询习题

一、素材 -- Active: 1714203732007127.0.0.13306db_stu -- 1.创建student和score表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR(20) , address VARCHAR(50) ); -- 创建…

模块化程序设计(函数的定义、调用、参数传递、局部变量、全局变量)

函数的引入: 我们曾经学习了程序设计中的三种基本控制结构(顺序、分支、循环)。用它们可以组成任何程序。但在应用中,还经常用到子程序结构。 通常,在程序设计中,我们会发现一些程序段在程序的不同地方反复…

android实现PhotoShop里的魔棒效果

魔棒是画板工具一个重要的功能,非常实用,只要轻轻一点,就能把触摸到的颜色区域选中,做复制、剪切、擦除等工作。 那怎么实现呢? 先来看看效果: 要实现这个效果,需要对安卓canvas和paint理解比…

数据结构----堆的实现(附代码)

当大家看了鄙人的上一篇博客栈后,稍微猜一下应该知道鄙人下一篇想写的博客就是堆了吧。毕竟堆栈在C语言中常常是一起出现的。那么堆是什么,是如何实现的嘞。接下来我就带大家去尝试实现一下堆。 堆的含义 首先我们要写出一个堆,那么我们就需…