设计模式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(); //展示简历1System.out.println("第二份简历:");resume2.display(); //展示简历2}
}

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

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

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

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

相关文章

蓝桥杯物联网竞赛_STM32L071_18_长短按键检测

长短按键的检测是国赛题里面遇到的,省赛没出过有两种实方法 定时器配置: 定时器的话要比delay准确,其中tim7定时器的准度最高 定时器预分配配置32 - 1,计数周期是10000 - 1这样做那么32MHZ/32也就是一秒钟记录10^6的数&#xf…

HR人才测评,什么是亲和力?如何提高亲和力?

什么是亲和力? 无论是熟人还是陌生人,在沟通之时,一些特定的人群总是给人一种非常融洽的感觉,让人在与其聊天之时没有任何的防备,可以畅所欲言,而这样的人就是具备亲和力的人。 在职场之中,…

Pytorch入门需要达到的效果

会搭建深度学习环境和依赖包安装 使用Anaconda创建环境、在pytorch官网安装pytorch、安装依赖包 会使用常见操作,例如matmul,sigmoid,softmax,relu,linear matmul操作见文章torch.matmul()的用法 sigmoid&#xff0…

Java多线程(02)

一、如何终止线程 终止线程就是要让 run 方法尽快执行结束 1. 手动创建标志位 可以通过在代码中手动创建标志位的方式,来作为 run 方法的执行结束条件; public static void main(String[] args) throws InterruptedException {boolean flag true;Thr…

基于AT89C52单片机的智能窗帘系统

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/89276984?spm1001.2014.3001.5503 C 源码仿真图毕业设计实物制作步骤07 智能窗户控制系统学院(部): 专 业: 班 级&…

双指针法和链表练习题(2024/5/28)

1面试题 02.07. 链表相交 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意&#xf…

系统管理、磁盘分区

系统管理 业务层面:为了满足一定的需求所做的特定操作。 硬盘是什么,硬盘的作用: **硬盘:**计算机的存储设备,机械硬盘是由一个或者多个磁性的盘组成,可以在盘片上进行数据的读写。 连接方式&#xff1a…

【Rust日报】Rust 中的形式验证

文章 - 未来的愿景:Rust 中的形式验证 这篇文章回顾了形式化验证的基本概念,作者展示了如何使用 Hoare triples 来描述和推理程序的正确性,以及如何使用分离逻辑来解决验证的复杂性。文章还解释了为什么 Rust 适用于形式化验证,以…

go ast语义分析实现指标计算器

什么是AST 首先我们要知道AST是什么(Abstract Syntax Tree,AST),简称为语法树,是go语言源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。 …

我的心情JSP+Servlet+JDBC+MySQL

系统概述 本系统采用JSPServletJDBCMySQL技术进行开发,包括查看我的心情列表, 编辑我的心情信息、新增我的心情。使用方法 将项目从idea中导入,然后配置项目的结构,包括jdk,库,模块,项目,工件…

QT 自定义协议TCP传输文件

后面附带实例的下载地址 一、将文件看做是由:文件头+文件内容组成,其中文件头包含文件的一些信息:文件名称、文件大小等。 二、文件头单独发送,文件内容切块发送。 三、每次发送信息格式:发送内容大小、发送内容类型(文件头或是文件块内容)、文件块内容。 四、效果展…

基于springboot实现政府管理系统项目【项目源码+论文说明】

基于springboot实现政府管理系统演示 摘要 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲&#xff…

饲料粉碎混合机组:打造精细化养殖

饲料粉碎混合机组是畜牧业和养殖业中不可或缺的设备。它集饲料粉碎和混合于一体,可以高效地处理各种饲料原料,提高饲料的均匀度和营养价值。 具体来说,饲料粉碎混合机组的主要功能包括将饲料原料进行粉碎,增加其表面积和调质粒度…

Steam游戏搬砖:靠谱吗,详细版说下搬砖中的核心内容!

可能大家也比较关注国外Steam游戏搬砖这个项目,最近单独找我了解的也比较多,其实也正常,因为现在市面上的项目很多都很鸡肋,而且很多都是一片红海,内卷太过严重,所以对于Steam的关注度也高很多,…

CTF-web-WP-攻防世界-1

1、view_source:打开开发者工具F12就能看到flag 2、robots (1)、使用目录扫描工具 工具:dirsearch命令:python dirsearch.py -u http://61.147.171.105:55644/ -e * (2)、看到下面有robots.txt文件,在URL后面输入&#xff0c…

INDICATOR 再c嵌入sql环境中的作用

在C语言嵌入SQL(Embedded SQL)的环境中,INDICATOR关键字用于处理数据库中的NULL值,以及管理与之相关联的宿主变量(host variables)。具体来说,它的作用主要体现在以下几个方面: NUL…

LeetCode题练习与总结:有序链表转换二叉搜索树--109

一、题目描述 给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为平衡二叉搜索树。 示例 1: 输入: head [-10,-3,0,5,9] 输出: [0,-3,9,-10,null,5] 解释: 一个可能的答案是[0,-3,9,-10,null,5],它表…

Docker安装Redis的详细教程

以下是一个使用Docker安装Redis的详细教程 1. 拉取Redis镜像 运行以下命令来从Docker Hub上拉取最新的Redis镜像: docker pull redis:latest如果您需要特定版本的Redis,可以指定版本号: docker pull redis:6.2.72. 运行Redis容器 以下命…

分享个自用的 Nginx 加强 WordPress 防护的规则

Nginx WordPress 的组合是目前非常普及的组合了,我们完全可以借助 Nginx 规则来加强 WordPress 的防护,提高 WordPress 的安全性,今天明月就给大家分享个自用的 Nginx 针对 WordPress 的防护规则,部分规则大家只需要根据自己的需要…

基于vuestic-ui实战教程 - 页面篇

1. 简介 前面介绍了基本的内容比如如何获取动态数据,下面就到登录进来后的页面实现了,相信各位读者或多或少都有 element-uijs 的实战经历,那么 vuestic-uits 实现的页面又该如何写呢?带着疑问开启今天的学习(声明由于…