设计模式---原型模式(Prototype)
来源:互联网 发布:我的邻居是exo网络剧 编辑:程序博客网 时间:2024/05/17 07:04
这个模式我看最早的一个版本的时候,我也没看懂,后来我换了一篇文章才看明白
先写一个简历类
//简历类public class Resume { //定义简历类需要的属性 private String name; private String sex; private String age; private String workTime; private String company; public Resume(String name) { this.name = name; } public void personalInfo(String sex, String age) { this.sex = sex; this.age = age; } public void workExperience(String workTime, String company) { this.workTime = workTime; this.company = company; } public void show() { System.out.println(name); System.out.println(age + "---" + sex); System.out.println(company + "---" + workTime); }}
调用简历类生成实体对象
public class Main { public static void main(String[] args) { //第一个版本调用方式 //比如说我要打印三分简历,我最原始的方法是这么做 Resume resume1 = new Resume("小鱼"); resume1.personalInfo("男","18"); resume1.workExperience("2006-2010","北京科技大学"); resume1.show(); Resume resume2 = new Resume("小鱼"); resume2.personalInfo("男","18"); resume2.workExperience("2006-2010","北京科技大学"); resume2.show(); Resume resume3 = new Resume("小鱼"); resume3.personalInfo("男","18"); resume3.workExperience("2006-2010","北京科技大学"); resume3.show(); System.out.println(resume1.equals(resume2));//false System.out.println(resume2.equals(resume3));//false //我稍微进步点的方法,我可能会这么做 Resume resumeA = new Resume("小鱼"); resumeA.personalInfo("男","18"); resumeA.workExperience("2006-2010","北京科技大学"); resumeA.show(); Resume resumeB = resumeA;// resumeB.personalInfo("男","18");// resumeB.workExperience("2006-2010","北京科技大学"); resumeB.show(); Resume resumeC = resumeA; resumeC.personalInfo("男","22岁"); resumeC.workExperience("2010-2013","清华大学"); resumeC.show(); resumeA.show(); System.out.println(resumeA.equals(resumeB));//true System.out.println(resumeB.equals(resumeC));//true }}
输出结果:
小鱼18---男北京科技大学---2006-2010小鱼18---男北京科技大学---2006-2010小鱼18---男北京科技大学---2006-2010falsefalse小鱼18---男北京科技大学---2006-2010小鱼18---男北京科技大学---2006-2010小鱼22岁---男清华大学---2010-2013小鱼22岁---男清华大学---2010-2013truetrue
从输出结果可以看出,由于三分简历引用的是同一个对象,导致我改简历C的时候,改变了简历A,因为他们引用是相同的嘛,指向地址相同。
为了避免这个问题的发生,我对简历类做了一些改造
//简历类 //实现接口Cloneable,这个接口叫标记接口,接口里啥都没定义。public class Resume implements Cloneable { //定义简历类需要的属性 private String name; private String sex; private String age; private String workTime; private String company; public Resume(String name) { this.name = name; } public void personalInfo(String sex, String age) { this.sex = sex; this.age = age; } public void workExperience(String workTime, String company) { this.workTime = workTime; this.company = company; } public void show() { System.out.println(name); System.out.println(age + "---" + sex); System.out.println(company + "---" + workTime); } public Resume createClone() throws CloneNotSupportedException { return (Resume) clone(); }}
然后运行,并看结果
public class Main { public static void main(String[] args) { Resume resumeA = new Resume("小王"); resumeA.personalInfo("男", "18"); resumeA.workExperience("2006-2010", "微软中国"); resumeA.show(); try { Resume cloneA1 = resumeA.createClone(); cloneA1.personalInfo("爷们", "23"); cloneA1.show(); Resume cloneA2 = resumeA.createClone(); cloneA2.workExperience("2050-2055","宇宙编程公司"); cloneA2.show(); resumeA.show(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } }}
从下面的输出结果可以发现简历A没有受到影响
小王18---男微软中国---2006-2010小王23---爷们微软中国---2006-2010小王18---男宇宙编程公司---2050-2055小王18---男微软中国---2006-2010
但是有一天我的需求又改了,我简历类的公司相关的内容要单独提取出来作为一个类存在
于是我将简历类改为如下两个类
package com.domain;public class Resume implements Cloneable { private String name; private String sex; private String age; private WorkExperience workExperience; public Resume(String name) { this.name = name; } public void personalInfo(String sex, String age) { this.sex = sex; this.age = age; } public void workExperience(WorkExperience workExperience) { this.workExperience = workExperience; } public Resume createClone() throws CloneNotSupportedException { return (Resume) clone(); } public void show() { System.out.println(name + "---" + sex + "---" + age+"---" + workExperience.getWorkTime() + "---" + workExperience.getCompany()); } public WorkExperience getWorkExperience() { return workExperience; } public void setWorkExperience(WorkExperience workExperience) { this.workExperience = workExperience; }}
package com.domain;public class WorkExperience { private String workTime; private String company; public WorkExperience(String workTime, String company) { this.workTime = workTime; this.company = company; } public String getWorkTime() { return workTime; } public void setWorkTime(String workTime) { this.workTime = workTime; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; }}
然后我运行,打印,发现问题
package com;import com.domain.Resume;import com.domain.WorkExperience;public class Main { public static void main(String[] args) { Resume resume = new Resume("明明"); resume.personalInfo("男", "22"); resume.workExperience(new WorkExperience("2000", "百度")); resume.show(); try { Resume clone = resume.createClone(); clone.show(); resume.getWorkExperience().setWorkTime("2022"); resume.getWorkExperience().setCompany("新浪"); resume.personalInfo("女", "40"); resume.show(); clone.show(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } }}
明明---男---22---2000---百度明明---男---22---2000---百度明明---女---40---2022---新浪明明---男---22---2022---新浪
产生这个现象的原因很明了了,因为clone()方法在复制基本类型的时候,复制的是值,
而复制引用类型的时候,复制的是地址值,被复制的对象的地址值还是指向原地址
这也就是我们常说的浅复制!!!
比如说数据集对象,DataSet()他就有clone()方法和copy()方法分别实现了浅复制和深复制。阅读全文
1 0
- 设计模式 原型Prototype
- prototype(原型设计模式)
- 设计模式--Prototype(原型)
- Prototype(原型)设计模式
- 设计模式-prototype原型
- 设计模式--原型模式(ProtoType)
- [设计模式]Prototype原型模式
- 设计模式--Prototype(原型模式)
- 设计模式 -- 原型模式Prototype
- 设计模式-原型模式(Prototype)
- [设计模式] 原型模式(Prototype)
- 设计模式-原型模式(Prototype)
- 【设计模式】-原型模式-Prototype
- 设计模式 原型模式 Prototype
- 设计模式:原型模式-prototype
- 设计模式---原型模式(Prototype)
- 设计模式 原型设计 Prototype
- 设计模式之Prototype(原型)
- MyBatis基础
- 从零开始搭建环境编写操作系统 AT&T GCC (八)使用键盘和滚轮鼠标
- 堆排序
- Error running Tomcat8: Address localhost:1099 is already in use 的错误
- 系统调用的一些函数
- 设计模式---原型模式(Prototype)
- 希尔排序
- LeetCode 513 Find Bottom Left Tree Value (BFS)
- 关于LYNC同步通讯录参数修改
- 机器学习-集成学习方法
- 红帽 重置 MAC地址
- wine下的字体乱码问题
- codemirror 常见操作
- vtkImagedata与vtkPolydata的减采样