原型模式,属于创建型设计模式中的一种,但是其不同于其余几种设计模式。它并未显式使用new关键字调用构造方法来初始化对象,而是通过调用clone方法来实现对象初始化。具体是怎么实现呢,我们还是通过一个实际问题来讲解。
我们在找工作的时候肯定都会写简历,但是我们会给不同的公司投,这时候,只有一份简历明显是不够的,你总得一家公司寄一份简历吧。所以我们要准备好若干份简历,投给不同的公司,但是这些简历的内容都是一样的。我们有两种方案来准备这些简历:
- 投多少家公司,就手写多少份简历
- 写一份简历,然后剩下的用复印机复印
现在我们从代码的角度来看这个问题,第一种方案就相当于所有的简历都使用new关键字来创建,而第二种方案,相当于使用new关键字创建出一个简历的实例,然后通过clone方法克隆出剩下的简历。
一份简历上的内容可谓是特别多,比如你的姓名,性别,生日,介绍,爱好等等,填一份简历会花费好长的时间。一般情况下,正常人都会选择上面的第二种方案,同样,使用代码实现也会使用clone方法来获取内容相同的实例,这就是所谓的原型模式。
实现的代码如下:
public class Resume implements Cloneable {
private String name;
private String birthday;
private boolean sex;
private String introduction;
private ArrayList<String> hobbies;
Resume(String name, String birthday, boolean sex, String introduction, ArrayList<String> hobbies){
this.name = name;
this.birthday = birthday;
this.sex = sex;
this.introduction = introduction;
this.hobbies = hobbies;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public String getIntroduction() {
return introduction;
}
public void setIntroduction(String introduction) {
this.introduction = introduction;
}
public ArrayList<String> getHobbies() {
return hobbies;
}
public void setHobbies(ArrayList<String> hobbies) {
this.hobbies = hobbies;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Test {
public static void main(String args[]) throws CloneNotSupportedException {
ArrayList<String> hobbies = new ArrayList<String>();
hobbies.add("跑步");
hobbies.add("听音乐");
Resume resume1 = new Resume("小明", "2000年1月1日", true, "我是一名热爱编程的程序员", hobbies);
Resume resume2 = (Resume) resume1.clone();
System.out.println("resume1和resume2是否为同一对象: " + (resume1 == resume2));
}
}
程序运行截图如下:
使用了原型模式后,我们就可以轻松的进行对象的复制,不需要再想之前一样耗费时间和精力去调用构造方法创建对象。但要注意使用上述的clone方法时要使类实现cloneable接口,否则在调用clone方法时会报异常。
通过在main方法中的测试,我们发现通过clone方法创建了一个新对象,但是新对象中的hobbies却是旧对象中的引用。因此,我们可以发现,clone方法是浅拷贝。
现在我们已经了解了什么是原型模式,我们再来总结一下原型模式的优点和缺点。原型模式简化了复杂对象的创建过程,提高了开发效率,但是如果想要实现深拷贝则需要较为复杂的代码。
关于深拷贝和浅拷贝,大家自行度娘,掌握了这两个概念更容易理解Java内存管理机制。