前言
原型设计模式是一种创建型设计模式,允许一个对象再创建另一个可定制的对象,无需知道如何创建对象的细节,springmvc框架中的单例(singleton)与多例(prototype)正是基于该设计模式而设计的。原型设计模式分为俩种,一种是浅拷贝,另一种是深拷贝。浅拷贝指的是对于基本数据类型和引用类型的变量通过值传递和引用传递,通俗易懂的说法就是,原对象的任何更改都会影响到克隆对象。而深拷贝是通过完整的克隆,重新创建一个新的对象,原对象的更改不会影响到克隆对象。浅拷贝通过实现Cloneable接口,重写clone方法实现。深拷贝可以通过重写clone方法或者实现Serializable序列化接口,通过序列化实现对象深拷贝。多用于复杂对象的创建,简化对象创建过程。本节我们以克隆多莉羊为例,实现原型模式的一个案例。
正文
浅拷贝
- 创建多莉羊类
package com.yundi.atp.dp.prototype.shallow;
/**
* @Author: 北溟溟
* @Description: 原型设计模式:浅拷贝,创建一只多莉羊并实现其Cloneable接口
* @Date: 2022/3/16 9:23
* @Version: 1.0.0
*/
public class SheepClone implements Cloneable {
/**
* 名称
*/
private String name;
/**
* 产地
*/
private SheepAddress sheepAddress;
public void printSheep() {
System.out.println(name + ":" + "是一只克隆羊!");
}
public SheepClone(String name, SheepAddress sheepAddress) {
this.name = name;
this.sheepAddress = sheepAddress;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public SheepAddress getSheepAddress() {
return sheepAddress;
}
public void setSheepAddress(SheepAddress sheepAddress) {
this.sheepAddress = sheepAddress;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
SheepClone sheep = new SheepClone("多莉", new SheepAddress("内蒙古", "呼和浩特市"));
sheep.printSheep();
System.out.println("sheep:" + sheep.hashCode() + "--------" + "sheepAddress:" + sheep.sheepAddress.hashCode() + "-------" + sheep.sheepAddress.getProvince() + "-------" + sheep.sheepAddress.getCity());
//调用克隆方法克隆一只多莉羊
SheepClone cloneSheep = (SheepClone) sheep.clone();
cloneSheep.printSheep();
//更改多莉羊的产地
sheep.getSheepAddress().setProvince("新疆");
sheep.getSheepAddress().setCity("乌鲁木齐");
//克隆的多莉羊属性
System.out.println("cloneSheep:" + cloneSheep.hashCode() + "--------" + "sheepAddress:" + cloneSheep.sheepAddress.hashCode() + "-------" + cloneSheep.sheepAddress.getProvince() + "-------" + cloneSheep.sheepAddress.getCity());
}
}
- 创建多莉羊产地类
package com.yundi.atp.dp.prototype.shallow;
/**
* @Author: 北溟溟
* @Description: 羊的产区
* @Date: 2022/3/22 14:58
* @Version: 1.0.0
*/
public class SheepAddress {
private String province;
private String city;
public SheepAddress(String province, String city) {
this.province = province;
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
深拷贝
- 创建多莉羊类
package com.yundi.atp.dp.prototype.deep;
import java.io.*;
/**
* @Author: 北溟溟
* @Description: 原型设计模式:深拷贝
* @Date: 2022/3/16 9:23
* @Version: 1.0.0
*/
public class SheepClone implements Cloneable, Serializable {
/**
* 名称
*/
private String name;
/**
* 产地
*/
private SheepAddress sheepAddress;
public void printSheep() {
System.out.println(name + ":" + "是一只克隆羊!");
}
public SheepClone(String name, SheepAddress sheepAddress) {
this.name = name;
this.sheepAddress = sheepAddress;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 方式一: 通过重写clone方法实现深拷贝
*
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
//完成对属性为基本数据类型和String的克隆
Object deep = super.clone();
SheepClone sheepClone = (SheepClone) deep;
sheepClone.sheepAddress = (SheepAddress) sheepAddress.clone();
return sheepClone;
}
/**
* 方式二: 通过序列化反序列化实现深拷贝(推荐使用)
*
* @return
*/
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);
SheepClone sheepClone = (SheepClone) ois.readObject();
return sheepClone;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
//关闭流
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e2) {
System.out.println(e2.getMessage());
}
}
}
public static void main(String[] args) throws CloneNotSupportedException {
SheepClone sheep = new SheepClone("多莉", new SheepAddress("内蒙古", "呼和浩特市"));
sheep.printSheep();
System.out.println("sheep:" + sheep.hashCode() + "--------" + "sheepAddress:" + sheep.sheepAddress.hashCode());
SheepClone cloneSheepOne = (SheepClone) sheep.clone();
cloneSheepOne.printSheep();
System.out.println("cloneSheep:" + cloneSheepOne.hashCode() + "--------" + "sheepAddress:" + cloneSheepOne.sheepAddress.hashCode());
SheepClone cloneSheepTwo = (SheepClone) sheep.clone();
cloneSheepTwo.printSheep();
System.out.println("cloneSheep:" + cloneSheepTwo.hashCode() + "--------" + "sheepAddress:" + cloneSheepTwo.sheepAddress.hashCode());
}
}
- 创建多莉羊产地
package com.yundi.atp.dp.prototype.deep;
import java.io.Serializable;
/**
* @Author: 北溟溟
* @Description: 羊的产区(测试引用对象的克隆)
* @Date: 2022/3/22 14:58
* @Version: 1.0.0
*/
public class SheepAddress implements Cloneable, Serializable {
private String province;
private String city;
public SheepAddress(String province, String city) {
this.province = province;
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
结语
本节关于原型设计模式的案例到这里就结束了,我们下期见。。。