原型模式:一种创建型的设计模式。
其本质是复制已经存在的实例,多用于资源耗费较多的大量对象的创建。可以拿孙悟空拔几根毫毛复制自己类比,原型模式就是实现自我复制。
GOF:Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype. (使用原型实例指定将要创建的对象类型,通过复制这个实例创建新的对象。)
在Java中可以直接使用Object类(所有java类的超类)提供的clone方法完成对象的克隆,实现原型模式。
UML类图:
1、prototype是原型类,声明一个克隆自己的接口
2、concreteprototype是具体的原型类,实现一个克隆自己的操作
3、client 让一个原型对象克隆自己
一个简单的案例:解决克隆羊问题。直接使用Java内Object的方法clone实现原型模式
package prototype;
public class Sheep implements Cloneable{
private String name;
private int age;
private String color;
public Sheep(String name, int age, String color) {
super();
this.name = name;
this.age = age;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String show()
{
return name+" "+age+" "+color;
}
//默认的克隆
protected Object clone()
{
Sheep sheep=null;
try
{
sheep=(Sheep)super.clone();
}catch(Exception e)
{
System.out.println(e.getMessage());
}
return sheep;
}
}
package prototype;
public class Client {
public static void main(String[] args) {
Sheep sheep1=new Sheep("Alex",12,"red");
Sheep sheep2=(Sheep)sheep1.clone();
Sheep sheep3=(Sheep)sheep1.clone();
Sheep sheep4=(Sheep)sheep1.clone();
Sheep sheep5=(Sheep)sheep1.clone();
Sheep sheep6=(Sheep)sheep1.clone();
Sheep sheep7=(Sheep)sheep1.clone();
System.out.println(sheep1.toString());
System.out.println(sheep2.toString());
System.out.println(sheep3.toString());
System.out.println(sheep4.toString());
System.out.println(sheep5.toString());
System.out.println(sheep6.toString());
System.out.println(sheep7.toString());
}
}
原型模式中的浅拷贝和深拷贝
浅拷贝和深拷贝区别:浅拷贝只是是引用的拷贝,地址还是那个地址,没有变化,拷贝再多本质上都只是把指针指向最初的那一个地址。而深拷贝却是申请新的空间和地址!
post一个我看过的很透彻的解释!
结论:Java中的clone方法是浅拷贝。
那么我们如何实现深拷贝呢?
两种方法:
1、直接使用clone对引用类型进行克隆,弊端是需要一个一个克隆,当对象个数比较多的时候太麻烦
2、利用序列化和反序列化
package deepclone;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class DeepProtoType implements Serializable , Cloneable{
public String name;//String属性
public DeepCloneableTarget deepCloneableTarget;//引用类型
public DeepProtoType(){
super();
}
//深拷贝-方式1:使用clone
protected Object clone() throws CloneNotSupportedException{
Object deep = null;
deep = super.clone();
DeepProtoType deepProtoType = (DeepProtoType)deep;
deepProtoType.deepCloneableTarget=(DeepCloneableTarget)deepCloneableTarget.clone();
return deepProtoType;
}
//deep 序列化copy by object serialiable
public Object deepClone() {
ByteArrayOutputStream bos=null;
ObjectOutputStream oos=null;
ByteArrayInputStream bis=null;
ObjectInputStream ois=null;
try {
//序列化
bos=new ByteArrayOutputStream();
oos=new ObjectOutputStream(bos);
oos.writeObject(this);
//反序列化
bis=new ByteArrayInputStream(bos.toByteArray());
ois=new ObjectInputStream(bis);
DeepProtoType copyObj=(DeepProtoType)ois.readObject();
return copyObj;
}catch(Exception e)
{
e.printStackTrace();
return null;
}finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}