中山网站制作策划,施工企业公路工程审图ppt,大型门户网站开发,wordpress词 条主题原型模式
缘起
某天#xff0c;小明的Leader找到小明:“小明啊#xff0c;如果有个发简历的需求#xff0c;就是有个简历的模板#xff0c;然后打印很多份#xff0c;要去一份一份展示出来#xff0c;用编程怎么实现呢#xff1f;”
小明一听#xff0c;脑袋里就有了…原型模式
缘起
某天小明的Leader找到小明:“小明啊如果有个发简历的需求就是有个简历的模板然后打印很多份要去一份一份展示出来用编程怎么实现呢”
小明一听脑袋里就有了思路二十分钟后给了一版代码
// 简历类
public 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);}
}客户端代码
public static void main(String[] args) {Resume resume1 new Resume(小明);resume1.setPersonalInfo(男, 22);resume1.setWorkExperience(2021-2023, XX公司);Resume resume2 new Resume(小明);resume2.setPersonalInfo(男, 22);resume2.setWorkExperience(2021-2023, XX公司);Resume resume3 new Resume(小明);resume1.setPersonalInfo(男, 22);resume1.setWorkExperience(2021-2023, XX公司);resume1.display();resume2.display();resume3.display();}Leader看后说道“挺好这其实就是我当年手写简历时代的代码哈哈哈三份简历需要实例化三次。你觉得这样会不会麻烦呢如果二十份简历你就要实例化二十次是不是而且如果你写错了一个字那你就要改20次你可以这么写”
public class Test {public static void main(String[] args) {Resume resume1 new Resume(小明);resume1.setPersonalInfo(男, 22);resume1.setWorkExperience(2021-2023, XX公司);Resume resume2 resume1;Resume resume3 resume1;resume1.display();resume2.display();resume3.display();}
}“其实就是传递引用对象而不是传值这样做就如同是在resume2、resume3纸上是空白的而将resume1上的内容粘贴到了resume2、resume3上面你还有没有其他的方式能实现呢比如emmmClone克隆”。
原型模式
忙活了好一会儿小明找到了一个相关的设计模式–原型模式。
原型模式(Prototype)用原型实例指定创建对象的种类并且通过复制这些原型创建的对象。 原型模式其实就是从一个对象再创建另外一个可制定的对象而且不需要知道任何的创建细节。
看下基本原型模式的代码。
原型类
// 原型类
public abstract class Prototype implements Cloneable{private String id;public Prototype(String id) {this.id id;}public String getId() {return id;}Overrideprotected Object clone() {Object object null;try {object super.clone();} catch (CloneNotSupportedException e) {System.out.println(克隆异常);}return object;}
}具体原型类
public class ConcretePrototype extends Prototype {public ConcretePrototype(String id) {super(id);}
}客户端调用
ConcretePrototype p1 new ConcretePrototype(123456);
System.out.println(原型ID: p1.getId());ConcretePrototype p2 (ConcretePrototype) p1.clone();
System.out.println(克隆ID: p2.getId());这样子只需要实例化一个对象其他的类实例化时只需要克隆这个对象即可。
对于Java而言那个原型抽象类Prototype是用不到的因为克隆实在是太常用了所以Java提供了Cloneable接口其中有一个唯一的方法就是clone()我们只需要实现这个接口就可以完成原型模式了。
简历原型模式实现
小明二十分钟后第二版代码出炉了。
// 简历类
public 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.age this.age);System.out.println(工作经历 this.timeArea this.company);}Overrideprotected Resume clone() throws CloneNotSupportedException {return (Resume) super.clone();}
}客户端调用
public class Test {public static void main(String[] args) throws CloneNotSupportedException {Resume resume1 new Resume(小明);resume1.setPersonalInfo(男, 22);resume1.setWorkExperience(2021-2023, XX公司);Resume resume2 resume1.clone();Resume resume3 resume1.clone();resume1.display();resume2.display();resume3.display();}
}// 结果如下
小明 男 22
工作经历 2021-2023 XX公司
小明 男 22
工作经历 2021-2023 XX公司
小明 男 22
工作经历 2021-2023 XX公司Leader看后点了点头“一般在初始化的信息不发生变化的情况下克隆就是最好的办法。这既隐藏了对象的创建细节又对性能是大大的提高。不用重新初始化对象而是动态获得对象运行时的状态。”
Leader接着又问道:“别高兴太早了你知道这种clone有什么弊端吗或者说是需要注意的点呢”
小明摇了摇头Leader接着说:“你知道深浅拷贝吧如果字段是值类型的则对该字段逐位复制如果是引用类型的则只复制引用不复制引用的对象因此原始对象及其副本中的引用都是同一个对象”。
“你先把工作经历单独抽离出来然后用简历类使用它们。”
小明不到十分钟改完了。
简历类
// 简历类
public 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());}Overrideprotected Resume clone() throws CloneNotSupportedException {return (Resume) super.clone();}
}工作经历类
public class WorkExperience {private String timeArea;private String company;public String getTimeArea() {return timeArea;}public void setTimeArea(String timeArea) {this.timeArea timeArea;}public String getCompany() {return company;}public void setCompany(String company) {this.company company;}
}客户端
public class Test {public static void main(String[] args) throws CloneNotSupportedException {Resume resume1 new Resume(小明);resume1.setPersonalInfo(男, 22);resume1.setWorkExperience(2021-2023, XX公司);Resume resume2 resume1.clone();resume2.setWorkExperience(2001-2003, ABC集团);Resume resume3 resume1.clone();resume2.setWorkExperience(2005-2007, ABC公司);resume1.display();resume2.display();resume3.display();}
}// 执行结果如下
小明 男 22
工作经历 2005-2007 ABC公司
小明 男 22
工作经历 2005-2007 ABC公司
小明 男 22
工作经历 2005-2007 ABC公司“看明白了吧一个原型两个副本它们的workExperience对象全都是同一个引用所以你改一个其他的全都变了这就是浅复制了。而我需要它们的workExperience对象全都是复制的对象不能相同。”
简历深拷贝实现
“实现这个其实很简单就是你的被引用对象也去实现Cloneable接口实现clone()方法然后在引用类中将它们处理下就行了快去查下相关资料实现一下试试”。
小明半小时后新的代码又出炉了。
WorkExperience工作经历类
public class WorkExperience implements Cloneable{private String timeArea;private String company;Overrideprotected WorkExperience clone() throws CloneNotSupportedException {return (WorkExperience) super.clone();}.....
}简历类
// 简历类
public class Resume implements Cloneable{private String name;private String sex;private String age;private WorkExperience work;....Overrideprotected Resume clone() throws CloneNotSupportedException {// 处理引用的对象Resume r (Resume) super.clone();r.work this.work.clone();return r;}
}再来测试下。
小明 男 22
工作经历 2021-2023 XX公司
小明 男 22
工作经历 2005-2007 ABC公司
小明 男 22
工作经历 2021-2023 XX公司总结
浅复制被复制对象的所有变量都含有与原来的对象相同的值而所有的对其他对象的引用都仍然指向原来的对象。
深复制把引用对象的变量指向复制过的新对象而不是原有的被引用的对象。