设计模式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…

【编译原理】小型语法编译器-Gradio界面设计

前言 本文部分内容来自网上搜集与个人实践。如果任何信息存在错误,欢迎读者批评指正。本文仅用于学习交流,不用作任何商业用途。 欢迎订阅专栏Gradio 文章目录 前言all/gui.pylexical_analysis.py导入库定义辅助函数 analyze_token定义词法分析函数 lexical_analysis测试代码总…

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

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

常见的MySQL语句类型及其基础用法

MySQL语句主要用于在MySQL数据库管理系统中执行各种操作,包括数据的检索、插入、更新、删除以及数据库结构的管理。下面是一些常见的MySQL语句类型及其基础用法详解: 1. SELECT 语句 - 查询数据 最基本的数据检索语句,用于从数据库中选取数…

uniapp 解决华为上架被拒问题,APP在申请敏感权限时,应同步说明权限申请的使用目的

1、store/modules/permission.js // app权限申请处理 const state {// 处理应用程序权限请求CAMERA: false,WRITE_EXTERNAL_STORAGE: false,ACCESS_FINE_LOCATION: false,CALL_PHONE: false,isIos: uni.getSystemInfoSync().platform ios,mapping: {CAMERA: {title: 摄像头权…

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…

Flutter 中的 CupertinoTabBar 小部件:全面指南

Flutter 中的 CupertinoTabBar 小部件:全面指南 在 Flutter 的 Cupertino 组件库中,CupertinoTabBar 是一个用于创建 iOS 风格底部导航栏的 widget。它为用户提供了一个直观的界面,可以快速在不同的标签页之间切换。本文将详细介绍 Cupertin…

MySQL分库分表:原理、实现与优化

推荐一个程序员的常用工具网站,嘎嘎好用:程序员常用工具 云服务器限时免费领:轻量服务器2核4G MySQL分库分表:原理、实现与优化 在现代互联网应用中,随着数据量的迅速增长和访问量的激增,单个数据库的性…

基于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语言源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。 …

SCSS基本使用:解锁CSS预处理器的高效与优雅

SCSS基本使用:解锁CSS预处理器的高效与优雅 一、SCSS初探:从CSS到预处理的飞跃1.1 SCSS基础概念1.2 安装与使用安装Sass编译SCSS 二、SCSS核心特性与实践2.1 变量2.2 嵌套2.3 混合(Mixins)2.4 继承2.5 运算 三、实战技巧与最佳实践…

Python怎么得到 xxx/xxx/xxx/abc.bag中的abc.bag?

在Python中,从一个完整的文件路径中提取文件名(如abc.bag),可以使用os.path模块中的basename函数。下面是一个例子: python import os # 假设这是你的完整文件路径 full_path "xxx/xxx/xxx/abc.bag" # 使…

我的心情JSP+Servlet+JDBC+MySQL

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

基于低代码的数智化融通研究

低代码平台简介 在信息化时代的浪潮中,软件应用开发扮演着至关重要的角色。然而,传统的软件开发方式往往需要开发人员具备深厚的编程基础和丰富的经验,这使得应用开发的门槛较高,开发周期较长,效率相对较低。为了解决这…

QT 自定义协议TCP传输文件

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

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

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