原型模式,使用原型实例定义/制定被创建对象种类/类型,通过拷贝原型实例创建新对象。
应用场景:(1)当某个类指定在运行时实例化。
(2)减少子类数量。
(3)降低昂贵类型新对象创建成本。
缺点:(1)clone方法可能实现比较困难。
(2)不适用于含循环引用的类结构。
结构图:

在看原型模式之前,有必要先简单看一下深复制和浅复制:
浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的其他对象的引用都仍然指向原来的对象。
深复制:把引用对象的变量指向复制过来的新对象,而不是原有的被引用对象。
一个原型模式的例子:如果需要很多份简历,这些简历之间除了个别信息其他都是相同的,如果一个一个新建、实例化,工作量会很大,因为一份简历需要填写的内容很多。这时候就可以用原型模式,只要克隆一下第一份简历再简单修改个别信息就可以了。以下是类图和java实现,我们假设每份简历除了工作经历之外,其他信息都相同。
(1)ICloneable接口:
package 原型模式;
public interface ICloneable {
public Object Clone();
}
(2)WorkExperience类:
package 原型模式;
public class WorkExperience implements ICloneable{
private String workDate;
private String company;
public WorkExperience(String date,String comp) {
this.workDate = date;
this.company = comp;
}
public void setWorkDate(String date) {
this.workDate=date;
}
public void setCompany(String comp) {
this.company = comp;
}
public String getWorkDate() {
return this.workDate;
}
public String getCompany() {
return this.company;
}
@Override
public Object Clone() {
return this.Clone();
}
}
(3)Resume类:
package 原型模式;
public class Resume implements ICloneable{
private String name;
private String sex;
private String age;
private WorkExperience work;
public Resume(String name,String sex,String age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public void setWorkExperience(WorkExperience work) {
this.work = work;
}
public void Display() {
System.out.println(name+" " +sex+" "+age);
System.out.println("工作经历:"+work.getWorkDate()+" "+work.getCompany());
}
@Override
//深复制实现
public Object Clone() {
Resume obj = new Resume(this.name,this.sex,this.age);
obj.setWorkExperience(this.work);
return obj;
}
}
(4)客户端调用:
package 原型模式;
public class Main {
public static void main(String[] args) {
Resume a = new Resume("哈哈","女","25岁");
a.setWorkExperience(new WorkExperience("1998-2000","A公司"));
Resume b = (Resume)a.Clone();
b.setWorkExperience(new WorkExperience("2000-2003","B公司"));
Resume c = (Resume)a.Clone();
c.setWorkExperience(new WorkExperience("2003-2009","C公司"));
a.Display();
b.Display();
c.Display();
}
}
输出结果: