在一个特定的场景中经常需要出现多个相同但状态各异的对象,通常的解决方法是通过new创建这些对象之后分别去设置这些对象的状态。原型设计模式提供了更快捷、更有效的解决方法。
通过clone()方法来复制一个指定类型的对象来创建更多同类型的对象。这个指定的对象可被称为“原型”对象,也就是通过复制原型对象来得到更多同类型的对象。
我们以克隆多利羊为例,有颜色,大小,角三个属性,sheep 必须实现 Cloneabe接口,否则报CloneNotSupportedException错误。
import java.io.*;
public class Sheep implements Cloneable,Serializable {
private String color;
private Angle angle;
private int size;
//浅复制
public Object clone(){
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("Sheep is not Cloneable");
}
return object;
}
//深复制
public Object deepClone()throws IOException,ClassNotFoundException{ //深克隆
ByteArrayOutputStream bo=new ByteArrayOutputStream();
ObjectOutputStream oo=new ObjectOutputStream(bo);
oo.writeObject(this);
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
return oi.readObject();
}
public Sheep(Angle angle,String color,int size){
this.angle = angle;
this.color=color;
this.size=size;
}
//seter,getter方法省略
}
public class Angle implements Serializable{
private int length;
public Angle(int len){
this.length=len;
}
//seter,getter方法省略
}
public class Client {
public static void main(String[] agrs) throws IOException, ClassNotFoundException {
Angle angle=new Angle(2);
Sheep mother =new Sheep(angle,"white",40);
Sheep dolly = (Sheep)mother.clone();
System.out.println("mother angle="+ mother.getAngle());
System.out.println("dolly angle="+ dolly.getAngle());
System.out.println("mother angle="+ mother.getAngle().getLength());
System.out.println("dolly angle="+ dolly.getAngle().getLength());
System.out.println("mother color="+ mother.getColor());
System.out.println("dolly color="+ dolly.getColor());
System.out.println("mother size="+ mother.getSize());
System.out.println("dolly size="+ dolly.getSize());
angle.setLength(3);
mother.setAngle(angle);
mother.setColor("Glay");
mother.setSize(41);
System.out.println("---------------after change------------------");
System.out.println("mother angle="+ mother.getAngle());
System.out.println("dolly angle="+ dolly.getAngle());
System.out.println("mother angle="+ mother.getAngle().getLength());
System.out.println("dolly angle="+ dolly.getAngle().getLength());
System.out.println("mother color="+ mother.getColor());
System.out.println("dolly color="+ dolly.getColor());
System.out.println("mother size="+ mother.getSize());
System.out.println("dolly size="+ dolly.getSize());
}
}
//output
mother angle=com.design.Prototype.Angle@1a758cb
dolly angle=com.design.Prototype.Angle@1a758cb
mother angle=2
dolly angle=2
mother color=white
dolly color=white
mother size=40
dolly size=40
---------------after change------------------
mother angle=com.design.Prototype.Angle@1a758cb
dolly angle=com.design.Prototype.Angle@1a758cb
mother angle=3
dolly angle=3
mother color=Glay
dolly color=white
mother size=41
dolly size=40
若是 Sheep dolly = (Sheep)mother.clone();改为 Sheep dolly = (Sheep)mother.deepClone();
mother angle=com.design.Prototype.Angle@60aeb0
dolly angle=com.design.Prototype.Angle@19b49e6
mother angle=2
dolly angle=2
mother color=white
dolly color=white
mother size=40
dolly size=40
---------------after change------------------
mother angle=com.design.Prototype.Angle@60aeb0
dolly angle=com.design.Prototype.Angle@19b49e6
mother angle=3
dolly angle=2
mother color=Glay
dolly color=white
mother size=41
dolly size=40
从上面的输出结果我们可以看出使用Object.clone()方法只能浅层次的克隆,即只能对那些成员变量是基本类型或String类型的对象进行克隆,对哪些成员变量是类类型的对象进行克隆Prototype对象都共享同一个temp实例。