原型模式
原型模式
克隆羊的问题
传统方案解决
package com.sky.prototype; /** * 羊 */ public class Sheep { private String name; // 姓名 private int age; // 年龄 private String color; // 颜色 public Sheep(String name, int age, String color) { 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; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", color='" + color + '\'' + '}'; } } package com.sky.prototype; /** * 客户端 */ public class Client { public static void main(String[] args) { // 传统方法 Sheep sheep1 = new Sheep("tom", 1, "白色"); Sheep sheep2 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor()); Sheep sheep3 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor()); Sheep sheep4 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor()); Sheep sheep5 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor()); Sheep sheep6 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor()); // ... System.out.println(sheep1); System.out.println(sheep2); System.out.println(sheep3); System.out.println(sheep4); System.out.println(sheep5); System.out.println(sheep6); } } 运行结果: Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'}
传统方案的优缺点
原型模式基本介绍:
使用原型模式解决克隆羊问题
package com.sky.prototype.improve; /** * 羊 */ public class Sheep implements Cloneable{ private String name; // 姓名 private int age; // 年龄 private String color; // 颜色 public Sheep(String name, int age, String color) { 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; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", color='" + color + '\'' + '}'; } // 重写clone方法 @Override protected Object clone() { Sheep sheep = null; try { sheep = (Sheep)super.clone(); } catch (CloneNotSupportedException e) { System.out.println(e.getMessage()); } return sheep; } } package com.sky.prototype.improve; /** * 客户端 */ public class Client { public static void main(String[] args) { System.out.println("使用原型模式进行对象的创建"); // 传统方法 Sheep sheep1 = new Sheep("tom", 1, "白色"); 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)sheep6.clone(); // ... System.out.println(sheep1); System.out.println(sheep2); System.out.println(sheep3); System.out.println(sheep4); System.out.println(sheep5); System.out.println(sheep6); System.out.println(sheep7); System.out.println(); System.out.println("sheep1 hashcode : " + sheep1.hashCode()); System.out.println("sheep2 hashcode : " + sheep2.hashCode()); System.out.println("sheep3 hashcode : " + sheep3.hashCode()); System.out.println("sheep4 hashcode : " + sheep4.hashCode()); System.out.println("sheep5 hashcode : " + sheep5.hashCode()); System.out.println("sheep6 hashcode : " + sheep6.hashCode()); System.out.println("sheep7 hashcode : " + sheep7.hashCode()); } } 使用原型模式进行对象的创建 Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} sheep1 hashcode : 356573597 sheep2 hashcode : 1735600054 sheep3 hashcode : 21685669 sheep4 hashcode : 2133927002 sheep5 hashcode : 1836019240 sheep6 hashcode : 325040804 sheep7 hashcode : 1173230247
原型模式中的浅拷贝和深拷贝
浅拷贝
package com.sky.prototype.simple; /** * 羊 浅拷贝 */ public class Sheep implements Cloneable{ private String name; // 姓名 private int age; // 年龄 private String color; // 颜色 public Sheep friend; // 这只羊有一个朋友 public Sheep(String name, int age, String color) { 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; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", color='" + color + '\'' + '}'; } // 重写clone方法 @Override protected Object clone() { Sheep sheep = null; try { sheep = (Sheep)super.clone(); } catch (CloneNotSupportedException e) { System.out.println(e.getMessage()); } return sheep; } } package com.sky.prototype.simple; /** * 客户端 */ public class Client { public static void main(String[] args) { System.out.println("使用原型模式进行对象的创建"); // 传统方法 Sheep sheep1 = new Sheep("tom", 1, "白色"); sheep1.friend = new Sheep("Jack", 2, "黑色"); 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)sheep6.clone(); // ... System.out.println(sheep1); System.out.println(sheep2); System.out.println(sheep3); System.out.println(sheep4); System.out.println(sheep5); System.out.println(sheep6); System.out.println(sheep7); System.out.println(); System.out.println("sheep1 hashcode : " + sheep1.hashCode() + " sheep1 hashcode : " + sheep1.friend.hashCode()); System.out.println("sheep2 hashcode : " + sheep2.hashCode() + " sheep2 hashcode : " + sheep1.friend.hashCode()); System.out.println("sheep3 hashcode : " + sheep3.hashCode() + " sheep3 hashcode : " + sheep1.friend.hashCode()); System.out.println("sheep4 hashcode : " + sheep4.hashCode() + " sheep4 hashcode : " + sheep1.friend.hashCode()); System.out.println("sheep5 hashcode : " + sheep5.hashCode() + " sheep5 hashcode : " + sheep1.friend.hashCode()); System.out.println("sheep6 hashcode : " + sheep6.hashCode() + " sheep6 hashcode : " + sheep1.friend.hashCode()); System.out.println("sheep7hashcode : " + sheep7.hashCode() + " sheep7 hashcode : " + sheep1.friend.hashCode()); } } 使用原型模式进行对象的创建 Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} Sheep{name='tom', age=1, color='白色'} sheep1 hashcode : 356573597 sheep1 hashcode : 1735600054 sheep2 hashcode : 21685669 sheep2 hashcode : 1735600054 sheep3 hashcode : 2133927002 sheep3 hashcode : 1735600054 sheep4 hashcode : 1836019240 sheep4 hashcode : 1735600054 sheep5 hashcode : 325040804 sheep5 hashcode : 1735600054 sheep6 hashcode : 1173230247 sheep6 hashcode : 1735600054 sheep7hashcode : 856419764 sheep7 hashcode : 1735600054
深拷贝
package com.sky.prototype.deepclone; import java.io.Serializable; public class DeepCloneableTarget implements Serializable,Cloneable { private static final long serialVersionUID = 1L; private String cloneName; private String cloneClass; public DeepCloneableTarget(String cloneName, String cloneClass) { this.cloneName = cloneName; this.cloneClass = cloneClass; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } package com.sky.prototype.deepclone; import java.io.*; public class DeepPrototype implements Serializable, Cloneable { public String name; // 属性 public DeepCloneableTarget deepCloneableTarget; // 引用类型 public DeepPrototype() { super(); } // 深拷贝 - 方式一 使用clone方法 @Override protected Object clone() throws CloneNotSupportedException { Object deep = null; // 这里完成对基本数据类型(属性)和String类型的克隆 deep = super.clone(); // 对引用类型的属性,进行单独的处理 DeepPrototype deepPrototype = (DeepPrototype) deep; // 对引用对象进行单独的拷贝 deepPrototype.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone(); return deepPrototype; } // 深拷贝 方式二 通过对象的序列化实现(推荐) 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 { ois.close(); bis.close(); oos.close(); bos.close(); } catch (Exception e) { System.out.println(e.getMessage()); } } } } package com.sky.prototype.deepclone; public class Client { public static void main(String[] args) throws Exception{ DeepPrototype p = new DeepPrototype(); p.name = "宋江"; p.deepCloneableTarget = new DeepCloneableTarget("大牛","小牛"); // 方式一 完成深拷贝 DeepPrototype p2 = (DeepPrototype)p.clone(); // 看看内存地址是不是一样的 System.out.println("p.name = " + p.name + "p.deepCloneableTarget = "+ p.deepCloneableTarget.hashCode()); System.out.println("p2.name = " + p.name + "p2.deepCloneableTarget = "+ p2.deepCloneableTarget.hashCode()); // 方式二 完成深拷贝 使用流的方式 // DeepPrototype p2 = (DeepPrototype) p.deepClone(); // System.out.println("p.name = " + p.name + "p.deepCloneableTarget = "+ p.deepCloneableTarget.hashCode()); // System.out.println("p2.name = " + p.name + "p2.deepCloneableTarget = "+ p2.deepCloneableTarget.hashCode()); } } 运行方式一: p.name = 宋江p.deepCloneableTarget = 356573597 p2.name = 宋江p2.deepCloneableTarget = 1735600054 运行方式二: p.name = 宋江p.deepCloneableTarget = 621009875 p2.name = 宋江p2.deepCloneableTarget = 1329552164
原型模式的注意事项和细节