原型模式是创建型模式的一种,其特点在于通过「复制」一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的「原型」,这个原型是可定制的。
Prototype原型模式是一种创建型设计模式,它主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。
例子:
public class WeeklyLog implements Cloneable
{
private String name;
private String date;
private String content;
public void setName(String name){
this.name = name;
}
public void setDate(String date){
this.date = date;
}
public void setContent(String content){
this.content = content;
}
public String getName(){
return (this.name);
}
public String getDate(){
return (this.date);
}
public String getContent(){
return (this.content);
}
public Object clone()
{
Object obj = null;
try
{
obj = super.clone();
return obj;
}
catch (CloneNotSupportedException e)
{
System.out.println("不能复制!");
return null;
}
}
}
public class Client
{
public static void main(String[] args) {
WeeklyLog log_previous = new WeeklyLog();
log_previous.setName("张三");
log_previous.setDate("2018年 第 12 周");
log_previous.setContent("这周工作很忙,每天加班!");
System.out.println("*** 周报 ***");
System.out.println(log_previous.getDate());
System.out.println(log_previous.getName());
System.out.println(log_previous.getContent());
System.out.println("-----------------------------------------");
WeeklyLog log_now;
log_now = (WeeklyLog)log_previous.clone();
log_now.setDate("2018年 第 13 周");
System.out.println("*** 周报 ***");
System.out.println(log_now.getDate());
System.out.println(log_now.getName());
System.out.println(log_now.getContent());
}
}
在本实例中使用了Java语言内置的潜克隆机制,通过继承Object类的clone()方法实现对象的复制,原始对象和克隆得到的对象在内存中是两个完全不同的对象,通过已创建的工作周报可以快速创建新的周报,然后再根据需要修改周报,无须再从头开始创建。原型模式为工作流系统中任务单的快速生成提供了一种解决方案。
浅克隆和深克隆
无论你是自己实现克隆方法,还是采用Java提供的克隆方法,都存在一个浅度克隆和深度克隆的问题。
只负责克隆按值传递的数据(比如基本数据类型、String类型),而不复制它所引用的对象,换言之,所有的对其他对象的引用都仍然指向原来的对象。
除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深度克隆把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制。
深度克隆要深入到多少层,是一个不易确定的问题。在决定以深度克隆的方式复制一个对象的时候,必须决定对间接复制的对象时采取浅度克隆还是继续采用深度克隆。因此,在采取深度克隆时,需要决定多深才算深。此外,在深度克隆的过程中,很可能会出现循环引用的问题,必须小心处理。