简历复印--原型模式

1.1 夸张的简历

        简历的打印。"对编程来说,简单的复制粘贴极有可能造成重复代码的灾难。我所说的意思你根本还没听懂。那就以刚才的例子,我出个需求你写写看,要求有一个简历类,必须要有姓名,可以设置性别和年龄,可以设置工作经历。最终我需要写三份简历。"

1.2 简历代码初步实现

package code.chapter9.prototype1;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		Resume resume1 = new Resume("大鸟");resume1.setPersonalInfo("男","29");resume1.setWorkExperience("1998-2000","XX公司");Resume resume2 = new Resume("大鸟");resume2.setPersonalInfo("男","29");resume2.setWorkExperience("1998-2000","XX公司");Resume resume3 = new Resume("大鸟");resume3.setPersonalInfo("男","29");resume3.setWorkExperience("1998-2000","XX公司");resume1.display();resume2.display();resume3.display();System.out.println();System.out.println("**********************************************");}
}//简历类
class Resume  {private String name;private String sex;private String age;private String timeArea;private String company;public Resume(String name){this.name=name;}//设置个人信息public void setPersonalInfo(String sex,String age){this.sex=sex;this.age=age;}//设置工作经历public void setWorkExperience(String timeArea,String company){this.timeArea=timeArea;this.company=company;}//展示简历public void display(){System.out.println(this.name +" "+this.sex +" "+this.age);System.out.println("工作经历 "+this.timeArea +" "+this.company);}
}

        "很好,这其实就是当年我手写简历的时代的代码。三份简历需要三次实例化。你觉得这样的客户端代码是不是很麻烦?如果要二十份,你就需要二十次实例化。""是呀,而且如果我写错了一个字,比如1998年改成1999年,那就要改二十次。""你为什么不这样写呢?

package code.chapter9.prototype2;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		Resume resume1 = new Resume("大鸟");resume1.setPersonalInfo("男","29");resume1.setWorkExperience("1998-2000","XX公司");Resume resume2 = resume1;Resume resume3 = resume1;resume1.display();resume2.display();resume3.display();System.out.println();System.out.println("**********************************************");}
}//简历类
class Resume  {private String name;private String sex;private String age;private String timeArea;private String company;public Resume(String name){this.name=name;}//设置个人信息public void setPersonalInfo(String sex,String age){this.sex=sex;this.age=age;}//设置工作经历public void setWorkExperience(String timeArea,String company){this.timeArea=timeArea;this.company=company;}//展示简历public void display(){System.out.println(this.name +" "+this.sex +" "+this.age);System.out.println("工作经历 "+this.timeArea +" "+this.company);}
}

        "哈,这其实是传引用,而不是传值,这样做就如同是在resume2纸张和resume3纸张上写着简历在resume1处一样,没有实际的内容。"

1.3 原型模式

原型模式(Prototype),用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。[DP]

原型模式(Prototype)结构图

"原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。我们来看看基本的原型模式代码。"

package code.chapter9.prototype0;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		ConcretePrototype p1 = new ConcretePrototype("编号123456");System.out.println("原ID:"+ p1.getID());ConcretePrototype c1 = (ConcretePrototype)p1.clone();System.out.println("克隆ID:"+ c1.getID());System.out.println();System.out.println("**********************************************");}
}//原型类
abstract class Prototype implements Cloneable {private String id;public Prototype(String id){this.id=id;}public String getID(){return this.id;}//原型模式的关键就是有这样一个clone方法public Object clone(){Object object = null;try {object = super.clone();}catch(CloneNotSupportedException exception){System.err.println("Clone异常。");}return object;}
}//具体原型类
class ConcretePrototype extends Prototype{public ConcretePrototype(String id){super(id);}}

        "哦,这样就可以不用实例化ConcretePrototype了,直接克隆就行了?
        "说得没错,就是这样的。但对于Java而言,那个原型抽象类Prototype是用不着的,因为克隆实在是太常用了,所以Java提供了Cloneable接口,其中就是唯一的一个方法clone(),这样你就只需要实现这个接口就可以完成原型模式了。现在明白了?去改我们的'简历原型'代码吧。"

1.4 简历的原型实现

package code.chapter9.prototype3;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		Resume resume1 = new Resume("大鸟");resume1.setPersonalInfo("男","29");resume1.setWorkExperience("1998-2000","XX公司");Resume resume2 = resume1.clone();resume2.setWorkExperience("2000-2003","YY集团");Resume resume3 = resume1.clone();resume3.setPersonalInfo("男","24");resume1.display();resume2.display();resume3.display();System.out.println();System.out.println("**********************************************");}
}//简历类
class Resume implements Cloneable {private String name;private String sex;private String age;private String timeArea;private String company;public Resume(String name){this.name=name;}//设置个人信息public void setPersonalInfo(String sex,String age){this.sex=sex;this.age=age;}//设置工作经历public void setWorkExperience(String timeArea,String company){this.timeArea=timeArea;this.company=company;}//展示简历public void display(){System.out.println(this.name +" "+this.sex +" "+this.age);System.out.println("工作经历 "+this.timeArea +" "+this.company);}//实现了clone接口方法public Resume clone(){Resume object = null;try {object = (Resume)super.clone();}catch(CloneNotSupportedException exception){System.err.println("Clone异常。");}return object;}
}

        这样一来,客户端的代码就清爽很多了,而且你要是想改某份简历,只需要对这份简历做一定的修改就可以了,不会影响到其他简历,相同的部分就不用再重复了。不过不知道这样子对性能是不是有大的提高呢?"
        "当然是大大提高,你想呀,每new一次,都需要执行一次构造函数,如果构造函数的执行时间很长,那么多次执行这个初始化操作就实在太低效了。一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这既隐藏了对象创建的细节,又对性能是大大的提高,何乐而不为呢?"
        "的确,我开始也没感觉到它的好,听你这么一说,感觉这样做的好处还真不少,它等于是不用重新初始化对象,而是动态地获得对象运行时的状态。这个模式真的很不错。

1.5 浅复制与深复制

        "别高兴得太早,如果我现在要改需求,你就又头疼了。你现在'简历'对象里的数据都是String型的,而String是一种拥有值类型特点的特殊引用类型,super.clone()方法是这样,如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其副本引用同一对象。什么意思呢?就是说如果你的'简历'类当中有对象引用,那么引用的对象数据是不会被克隆过来的。"
        "没太听懂,为什么不能一同复制过来呢?"

        "举个例子你就明白了,你现在的'简历'类当中有一个'设置工作经历'的方法,在现实设计当中,一般会再有一个'工作经历'类,当中有'时间区间'和'公司名称'等属性,'简历'类直接调用这个对象即可。

代码结构图

package code.chapter9.prototype4;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		Resume resume1 = new Resume("大鸟");resume1.setPersonalInfo("男","29");resume1.setWorkExperience("1998-2000","XX公司");Resume resume2 = resume1.clone();resume2.setWorkExperience("2000-2003","YY集团");Resume resume3 = resume1.clone();resume3.setPersonalInfo("男","24");resume3.setWorkExperience("2003-2006","ZZ公司");resume1.display();resume2.display();resume3.display();System.out.println();System.out.println("**********************************************");}
}//简历类
class Resume implements Cloneable {private String name;private String sex;private String age;private WorkExperience work;		//声明一个工作经历的对象public Resume(String name){this.name = name;this.work = new WorkExperience();//对这个工作经历对象实例化}//设置个人信息public void setPersonalInfo(String sex,String age){this.sex=sex;this.age=age;}//设置工作经历public void setWorkExperience(String timeArea,String company){this.work.setTimeArea(timeArea);//给工作经历实例的时间范围赋值this.work.setCompany(company);	//给工作经历实例的公司赋值}//展示简历public void display(){System.out.println(this.name +" "+this.sex +" "+this.age);System.out.println("工作经历 "+this.work.getTimeArea() +" "+this.work.getCompany());}public Resume clone(){Resume object = null;try {object = (Resume)super.clone();}catch(CloneNotSupportedException exception){System.err.println("Clone异常。");}return object;}
}//工作经历类
class WorkExperience {//工作时间范围private String timeArea;public String getTimeArea(){return this.timeArea;}public void setTimeArea(String value){this.timeArea=value;}//所在公司private String company;public String getCompany(){return this.company;}public void setCompany(String value){this.company=value;}
}

        结果显示,实际结果与期望结果并不符合,前两次的工作经历数据被最后一次数据给覆盖了。

        "通过写代码,并且去查了一下Java关于Cloneable的帮助,我大概知道你的意思了,由于它是浅表复制,所以对于值类型,没什么问题,对引用类型,就只是复制了引用,对引用的对象还是指向了原来的对象,所以就会出现我给resume1、resume2、resume3三个引用设置'工作经历',但却同时看到三个引用都是最后一次设置,因为三个引用都指向了同一个对象。"
        "你写的和说的都很好,就是这个原因,这叫作'浅复制',被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。但我们可能更需要这样的一种需求,把要复制的对象所引用的对象都复制一遍。比如刚才的例子,我们希望是resume1、resume2、resume3三个引用的对象是不同的,复制时就一变二,二变三,此时,我们就叫这种方式为'深复制',深复制把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。"
        "那如果'简历'对象引用了'工作经历','工作经历'再引用'公司','公司'再引用'职位'……这样一个引用一个,很多层,如何办?"
        "这的确是个很难回答的问题,深复制要深入到多少层,需要事先就考虑好,而且要当心出现循环引用的问题,需要小心处理,这里比较复杂,可以慢慢研究。就现在这个例子,问题应该不大,深入到第一层就可以了。"

1.6 简历的深复制实现

代码结构图

package code.chapter9.prototype5;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		Resume resume1 = new Resume("大鸟");resume1.setPersonalInfo("男","29");resume1.setWorkExperience("1998-2000","XX公司");Resume resume2 = resume1.clone();resume2.setWorkExperience("2000-2003","YY集团");Resume resume3 = resume1.clone();resume3.setPersonalInfo("男","24");resume3.setWorkExperience("2003-2006","ZZ公司");resume1.display();resume2.display();resume3.display();System.out.println();System.out.println("**********************************************");}
}//简历类
class Resume implements Cloneable {private String name;private String sex;private String age;private WorkExperience work;public Resume(String name){this.name = name;this.work = new WorkExperience();}//设置个人信息public void setPersonalInfo(String sex,String age){this.sex=sex;this.age=age;}//设置工作经历public void setWorkExperience(String timeArea,String company){this.work.setTimeArea(timeArea);//给工作经历实例的时间范围赋值this.work.setCompany(company);	//给工作经历实例的公司赋值}//展示简历public void display(){System.out.println(this.name +" "+this.sex +" "+this.age);System.out.println("工作经历 "+this.work.getTimeArea() +" "+this.work.getCompany());}public Resume clone(){Resume object = null;try {object = (Resume)super.clone();object.work = this.work.clone();}catch(CloneNotSupportedException exception){System.err.println("Clone异常。");}return object;}
}//工作经历类
class WorkExperience implements Cloneable {//工作时间范围private String timeArea;public String getTimeArea(){return this.timeArea;}public void setTimeArea(String value){this.timeArea=value;}//所在公司private String company;public String getCompany(){return this.company;}public void setCompany(String value){this.company=value;}public WorkExperience clone(){WorkExperience object = null;try {object = (WorkExperience)super.clone();}catch(CloneNotSupportedException exception){System.err.println("Clone异常。");}return object;}
}

1.7 复制简历vs.手写求职信

"如果是写代码,我当然会鼓励你去应用原型模式简化代码,优化设计。但对于求职,你是愿意你的简历和求职信倍受重视呢?还是愿意和所有的毕业生一样千篇一律毫无新意地碰运气?"

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

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

相关文章

web自动化测试系列-如何选择实战项目(四)

目录 1.项目安装 2.项目优点 3.项目介绍 3.1 项目介绍 3.3 商品展示 接上文 :web自动化测试系列-页面元素该如何定位?(三)-CSDN博客 在后续的技术操作中都将会使用到项目 ,如果你有自己的练手项目 ,优先拿自己的项目做练习&#xff0c…

【话题】如何看待那些速成并精通软件书籍的神器

大家好,我是全栈小5,欢迎阅读小5的系列文章,这是《话题》系列文章 目录 背景1. 神话与现实1.1 理论与实践之间的鸿沟1.2 一劳永逸的错觉 2. 速成书籍的优势与局限2.1 优势:2.2 局限: 3. 如何有效利用速成书籍3.1 量力而…

算法——链表(1)

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 小比特 大梦想 此篇文章与大家分享链表专题的第一部分 如果有不足的或者错误的请您指出! 1.链表常用技巧总结 1.1引入虚拟头结点 在力扣上,基本提供的链表题目都是"无头的",但是针对无头链表,我们最…

【话题】程序员35岁会失业吗?

大家好,我是全栈小5,欢迎阅读小5的系列文章,这是《话题》系列文章 目录 背景招聘分析一、技术更新换代的挑战二、经验与技术的双重优势三、职业发展的多元化选择四、个人成长与职业规划的平衡五、结语文章推荐 背景 35岁被认为是程序员职业生…

数据治理与大数据平台解决方案(免费|可下载)

1、知识星球下载: 如需下载完整PPTX可编辑源文件,请前往星球获取:https://t.zsxq.com/191Y7dD3p 2、免费领取步骤: 【1】关注公众号 方案驿站 【2】私信发送 数据治理与大数据平台 【3】获取本方案PDF下载链接,直接…

007 CSS的继承和层叠 元素特性

文章目录 CSS属性的继承CSS属性的层叠选择器的权重 HTML元素的类型编写HTML注意事项元素隐藏方法CSS属性-overflowCSS样式不生效可能原因 CSS属性的继承 如果一个属性具备继承性,那么在该元素上设置后,它的后代元素都可以继承这个属性 如果后代元素自己…

v-on内联语句

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>v-on内联语句</title> </head> …

如何用图形化工具远程连接MySQL或MariaDB

2024年4月7日&#xff0c;周日上午 在远程连接数据库时&#xff0c;可能会遇到如下问题&#xff1a; Lost connection to MySQL server at ‘reading initial communication packet, system error: 0 解决的办法 第一步&#xff1a;修改my.cnf my.cnf一般在/etc/mysql里面&a…

2023年度总结:允许迷茫,破除迷茫;专注自身,把握当下

0、前言 &#x1f4dc;为什么24年已经过了几个月&#xff0c;才提笔写这年度总结呢&#xff1f;毫不羞愧直问我的内心&#xff0c;其实就是懒罢了。直到前几天朋友看到了我去年写的总结&#xff0c;我自己点进那篇总结&#xff0c;完完整整的看了一遍&#xff0c;又翻看我23年…

C语言 | Leetcode C语言题解之第12题整数转罗马数字

题目&#xff1a; 题解&#xff1a; const char* thousands[] {"", "M", "MM", "MMM"}; const char* hundreds[] {"", "C", "CC", "CCC", "CD", "D", "DC"…

职业教育的痛点

一是毕业生不能满足产业的用人需求&#xff08;职教的经济属性&#xff09;。我国产业从中低端向中高端延伸&#xff0c;生产方式从流水线模式向复合化、集成化、绿色制造、柔性定制等转变&#xff0c;复合型的岗位增多。数字化转型要求每个岗位都需要掌握必要的“数字思维、数…

中国电子学会(CEIT)2021年12月真题C语言软件编程等级考试四级(含详细解析答案)

中国电子学会(CEIT)考评中心历届真题(含解析答案) C语言软件编程等级考试四级 2021年12月 编程题五道 总分:100分一、移动路线(25分) 桌子上有一个m行n列的方格矩阵,将每个方格用坐标表示,行坐标从下到上依次递增,列坐标从左至右依次递增,左下角方格的坐标为…

Go语言如何处理整数溢出

如果不了解在Go语言中如何处理整数溢出问题,可能会导致非常严重的错误。下面我们来讨论这个主题。在讨论之前,我们需要记住一些与整数有关的概念。 1. 概念 Go总共提供了10种整数类型。有4种有符号整数类型和4种无符号整数类型,具体如下表所示。 有符号整数无符号整数int8 …

Vue2(完结):replace属性、编程式路由导航、缓存路由组件、两个新钩子、路由守卫、history与hash

一、router-link的replace属性 1、作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式 2、浏览器的历史记录有两种写入方式&#xff1a;分别为push和replace&#xff0c;push是追加历史记录&#xff0c;replace是替换当前记录。路由跳转时候默认为push 3、如何开启repla…

4.6

数求和阶乘和质数 #include <iostream> using namespace std; int mproduct(int a) { if(a>1) { return a*mproduct((a-1)); } else { return 1; } } class number { int a; public: number():a(5){}; number(int a):a(a){…

HTTPS中的TLS和TCP能同时握手吗

一般情况下&#xff0c;不管 TLS 握手次数如何&#xff0c;都得先经过 TCP 三次握手后才能进行 因为 HTTPS 都是基于 TCP 传输协议实现的&#xff0c;得先建立完可靠的 TCP 连接才能做 TLS 握手的事情。 「HTTPS 中的 TLS 握手过程可以同时进行三次握手」对不对呢&#xff1f…

敏感信息泄露漏洞

法律声明 参与培训需要遵守国家法律法规&#xff0c;相关知识只做技术研究&#xff0c;请勿用于违法用途&#xff0c;造成任何后果自负与本人无关。 中华人民共和国网络安全法&#xff08;2017年6月1日起施行&#xff09; 第二十二条 任何个人和组织不得从事入侵他人网络、干扰…

C——找单身狗2

题目内容&#xff1a; 在一个数组中&#xff0c;室友两个数字出现了一次&#xff0c;其他所有数字都出现了两次。找出只出现一次的数字。 如&#xff1a;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff…

【云计算】云数据中心网络(一):VPC

云数据中心网络&#xff08;一&#xff09;&#xff1a;VPC 1.什么是 VPC2.VPC 的组成2.1 虚拟交换机2.2 虚拟路由器 3.VPC 网络规划3.1 VPC 数量规划3.2 交换机数量规划3.3 地址空间规划3.4 不同规模企业地址空间规划实践 4.VPC 网络高可靠设计4.1 单地域单可用区部署4.2 单地…

(delphi11最新学习资料) Object Pascal 学习笔记---第8章第7节(可视化窗体继承)

8.7 可视化窗体继承 ​ 继承不仅用于库类或你编写的类&#xff0c;而且在整个基于 Object Pascal 的开发环境中相当普遍。正如我们所看到的&#xff0c;当你在集成开发环境中创建一个窗体时&#xff0c;这个窗体就是一个继承自 TForm 的类的实例。因此&#xff0c;任何可视化应…