Prototype(原型模式)之深度克隆

继上篇深入浅出设计模式 —— Prototype(原型模式)的浅克隆实现, 本文进入Prototype(原型模式)的进阶篇—-深度克隆。

深度克隆 —- 序列化方式实现

把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫做反序列化(Deserialization)。写在流里的是对象的一个克隆(新的, 独立的), 而原对象仍存在于JVM内存模型里。因此, 以下代码采用序列化方式实现深度克隆。

第一步: 将上篇的代码做些许改动, 加入对象引用(以便测试浅克隆和深克隆的区别)。

原型接口:FruitPrototype保持不变

package com.wenniuwuren.prototype;/** * 原型接口 * @author wenniuwuren * */public interface FruitPrototype{public abstract FruitPrototype shallowClone() throws CloneNotSupportedException; }

原型具体实现 : 加入引用以及属性的getter和setter方法方便测试比较package com.wenniuwuren.prototype;/** * 原型具体实现 * @author wenniuwuren * */public class ConcteteFruitPrototype implements FruitPrototype, Cloneable{private String size;private String color; private Vitamins vitamins;public ConcteteFruitPrototype(String size, String color, Vitamins vitamins) {this.size = size;this.color = color;this.vitamins = vitamins;}// 克隆public FruitPrototype shallowClone() throws CloneNotSupportedException {return (FruitPrototype) super.clone();}// 方便打印public void display(String colorname) {System.out.println(colorname+"的大小是: "+size+" 颜色是:"+color);}public Vitamins getVitamins() {return vitamins;}public void setVitamins(Vitamins vitamins) {this.vitamins = vitamins;}public String getSize() {return size;}public void setSize(String size) {this.size = size;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}}原型管理类:FruitTool 保持不变package com.wenniuwuren.prototype;import java.util.HashMap;/** * 原型管理类 * @author wenniuwuren * */public class FruitTool {private HashMap<String, FruitPrototype> fruits = new HashMap<String, FruitPrototype>();public void put(String key, FruitPrototype fruitPrototype) {fruits.put(key, fruitPrototype);}public FruitPrototype get(String key) {return fruits.get(key);}}

水果都含有的维生素类:Vitamins为新增的对象引用类, 仅提供一个属性方便测试。

package com.wenniuwuren.prototype;/** * 水果都含有的维生素类 * @author wenniuwuren * */public class Vitamins {private Boolean isContainsVitaminA;public Boolean getIsContainsVitaminA() {return isContainsVitaminA;}public void setIsContainsVitaminA(Boolean isContainsVitaminA) {this.isContainsVitaminA = isContainsVitaminA;}}

测试类:

package com.wenniuwuren.prototype;import java.io.IOException;public class Client {public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {FruitTool fruitTool = new FruitTool();// 初始化水果的大小和颜色fruitTool.put("Apple", new ConcteteFruitPrototype("Middle", "Green", new Vitamins()));fruitTool.put("Watermelon", new ConcteteFruitPrototype("Large", "Red", new Vitamins()));fruitTool.put("Lemon", new ConcteteFruitPrototype("Small", "Yellow", new Vitamins()));System.out.println("#######################浅克隆测试########################");String fruitName = "Apple";ConcteteFruitPrototype concteteFruitPrototype1 = (ConcteteFruitPrototype) fruitTool.get(fruitName).shallowClone();concteteFruitPrototype1.display(fruitName);System.out.print("赋值前, 浅克隆后和浅克隆前的String类型数据相等:" );System.out.println(concteteFruitPrototype1.getColor().equals(((ConcteteFruitPrototype)fruitTool.get(fruitName)).getColor()));System.out.print("赋值前, 浅克隆后和浅克隆前的 对象引用相等:" );System.out.println(concteteFruitPrototype1.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool.get(fruitName)).getVitamins().getIsContainsVitaminA());System.out.println("—————-分别对克隆后对象赋值, 观察数据是否独立——————–");concteteFruitPrototype1.setColor("Red");System.out.print("赋值后,浅克隆后和浅克隆前的String类型数据相等:");System.out.println(concteteFruitPrototype1.getColor().equals(((ConcteteFruitPrototype)fruitTool.get(fruitName)).getColor()));concteteFruitPrototype1.getVitamins().setIsContainsVitaminA(Boolean.FALSE);System.out.print("赋值后, 浅克隆后和浅克隆前的 对象引用相等:" );System.out.println(concteteFruitPrototype1.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool.get(fruitName)).getVitamins().getIsContainsVitaminA());}}

数最亮的星。如果有可能,我带你去远行。

Prototype(原型模式)之深度克隆

相关文章:

你感兴趣的文章:

标签云: