原型模式:用一个已经创建的实例作为原型,根本无须知道对象创建的细节,通过复制该原型对象来创建一个和原型相同或相似的新对象
知识点:
1.Cloneable接口/Object#clone方法 详解
Cloneable是一个标记接口,需要和 Object.clone()配合使用;这是JAVA中实现对象拷贝必不可少的
2.浅拷贝/深拷贝
浅拷贝:指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象;
深拷贝:不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象
因此,当引用对象较多,或者存在嵌套引用的时候,实现起来较为复杂;因此可以考虑使用序列化机制实现。
3.序列化机制实现深拷贝
下面代码中展示了jvm和序列化两种实现深拷贝的方式
package com.tuling.designpattern.prototype;
import java.io.*;
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
BaseInfo baseInfo=new BaseInfo( "tuling" );
Product product=new Product( "part1", "part2", "part3", "part4", baseInfo );
Product clone=product.clone();
System.out.println( "original: " + product );
System.out.println( "clone: " + clone );
product.getBaseInfo().setCompanyName( "xxxx" );
System.out.println( "original: " + product );
System.out.println( "clone: " + clone );
}
}
class BaseInfo implements Cloneable, Serializable {
private String companyName;
public BaseInfo(String companyName) {
this.companyName=companyName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName=companyName;
}
@Override
protected BaseInfo clone() throws CloneNotSupportedException {
return ((BaseInfo) super.clone());
}
@Override
public String toString() {
return hashCode() + " ]BaseInfo{" +
"companyName='" + companyName + '\'' +
'}';
}
}
class Product implements Cloneable, Serializable {
static final long serialVersionUID=6772397503790075095L;
private String part1;
private String part2;
private String part3;
private String part4;
// 自定义数据类型
private BaseInfo baseInfo;
private String part5;
public Product(String part1, String part2, String part3, String part4, BaseInfo baseInfo) {
this.part1=part1;
this.part2=part2;
this.part3=part3;
this.part4=part4;
this.baseInfo=baseInfo;
}
public String getPart1() {
return part1;
}
public void setPart1(String part1) {
this.part1=part1;
}
public String getPart2() {
return part2;
}
public void setPart2(String part2) {
this.part2=part2;
}
public String getPart3() {
return part3;
}
public void setPart3(String part3) {
this.part3=part3;
}
public String getPart4() {
return part4;
}
public void setPart4(String part4) {
this.part4=part4;
}
public BaseInfo getBaseInfo() {
return baseInfo;
}
public void setBaseInfo(BaseInfo baseInfo) {
this.baseInfo=baseInfo;
}
@Override
protected Product clone() throws CloneNotSupportedException {
// 利用jvm克隆机制完成的深拷贝
// Product productClone= ((Product) super.clone());
// BaseInfo clone1=this.baseInfo.clone();
// productClone.setBaseInfo( clone1 );
// return productClone ;
// 序列化方式实现的深拷贝
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
try (ObjectOutputStream oos=new ObjectOutputStream( byteArrayOutputStream )) {
oos.writeObject( this );
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream( byteArrayOutputStream.toByteArray() );
try (ObjectInputStream ois=new ObjectInputStream( byteArrayInputStream )) {
Product o=((Product) ois.readObject());
return o;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
@Override
public String toString() {
return super.hashCode() + " ] Product{" +
"part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
", part3='" + part3 + '\'' +
", part4='" + part4 + '\'' +
", baseInfo='" + baseInfo + '\'' +
'}';
}
}