当前位置:网站首页 > 科技动态 > 正文

设计模式之原型模式

原型模式

原型模式,指将一个对象作为原型,对其进行复制、克隆,产生一个和原对象属性相同的新对象。

普通模式复制对象

调用对象的 get/set 方法设置属性

public class Sheep { private String name; private int age; 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; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + '}'; } } 
Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(1); Sheep sheep2 = new Sheep(); sheep2.setName(sheep.getName()); sheep2.setAge(sheep.getAge()); // 各属性相同,但对象的地址不同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); System.out.println("sheep:" + sheep.hashCode()); System.out.println("sheep2:" + sheep2.hashCode()); 

原型模式复制对象

public class Sheep implements Cloneable { private String name; private int age; 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; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() { Sheep sheep = null; try { sheep = (Sheep) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return sheep; } } 
Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(1); Sheep sheep2 = (Sheep) sheep.clone(); // 各属性相同,但对象的地址不同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); System.out.println("sheep:" + sheep.hashCode()); System.out.println("sheep2:" + sheep2.hashCode()); 

浅拷贝

基本数据类型

当成员变量是基本数据类型,浅拷贝会直接进行值传递,将该属性值复制一份给新对象。

引用数据类型

当成员变量是引用数据类型,浅拷贝会进行引用传递,将该属性的引用地址复制一份给新对象。 此时,新对象和原型对象的成员变量指向同一个实例,在一个对象中修改这个成员变量,另一个对象也会受到影响。

浅拷贝使用默认的 clone() 方法实现。

public class Dog implements Cloneable { private String name; private int age; 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; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() { Dog dog = null; try { dog = (Dog) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return dog; } } public class Sheep implements Cloneable { private String name; private int age; private Dog friend; 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 Dog getFriend() { return friend; } public void setFriend(Dog friend) { this.friend = friend; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}'; } @Override protected Object clone() { Sheep sheep = null; try { sheep = (Sheep) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return sheep; } } 
Dog friend = new Dog(); friend.setName("Tom"); friend.setAge(1); Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(2); sheep.setFriend(friend); Sheep sheep2 = (Sheep) sheep.clone(); // 属性值相同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); // 对象的地址不同 System.out.println("sheep.hashCode:" + sheep.hashCode()); System.out.println("sheep2.hashCode:" + sheep2.hashCode()); // 引用数据类型成员变量的地址相同 System.out.println("sheep.friend:" + sheep.getFriend().hashCode()); System.out.println("sheep2.friend:" + sheep2.getFriend().hashCode()); 

深拷贝

不论成员变量是基本数据类型还是引用数据类型,深拷贝都会复制一份新的给新对象。

实现方式 1:重写 clone() 实现深拷贝

public class Dog implements Cloneable { private String name; private int age; 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; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() { Dog dog = null; try { dog = (Dog) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return dog; } } public class Sheep implements Cloneable { private String name; private int age; private Dog friend; 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 Dog getFriend() { return friend; } public void setFriend(Dog friend) { this.friend = friend; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}'; } @Override protected Object clone() { Sheep sheep = null; try { // 对基本数据类型的拷贝 sheep = (Sheep) super.clone(); // 对引用数据类型的拷贝;需要引用类型也实现 Cloneable 接口 sheep.friend = (Dog) friend.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return sheep; } } 
Dog friend = new Dog(); friend.setName("Tom"); friend.setAge(1); Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(2); sheep.setFriend(friend); Sheep sheep2 = (Sheep) sheep.clone(); // 属性值相同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); // 对象的地址不同 System.out.println("sheep.hashCode:" + sheep.hashCode()); System.out.println("sheep2.hashCode:" + sheep2.hashCode()); // 引用数据类型成员变量的地址也不相同 System.out.println("sheep.friend:" + sheep.getFriend().hashCode()); System.out.println("sheep2.friend:" + sheep2.getFriend().hashCode()); 

实现方式 2:通过对象序列化实现深拷贝

public class Dog implements Serializable { private String name; private int age; 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; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } } // 所有相关对象都要实现 Serializable 接口,包括 Dog public class Sheep implements Serializable { private String name; private int age; private Dog friend; 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 Dog getFriend() { return friend; } public void setFriend(Dog friend) { this.friend = friend; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}'; } // 通过对象的序列化实现深拷贝 public Object deepClone() { Sheep copySheep = null; 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); copySheep = (Sheep) ois.readObject(); } catch (IOException | SecurityException | NullPointerException | ClassNotFoundException e) { e.printStackTrace(); } finally { try { if (bos != null) { bos.close(); } if (oos != null) { oos.close(); } if (bis != null) { bis.close(); } if (ois != null) { ois.close(); } } catch (IOException e) { e.printStackTrace(); } } return copySheep; } } 
Dog friend = new Dog(); friend.setName("Tom"); friend.setAge(1); Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(2); sheep.setFriend(friend); Sheep sheep2 = (Sheep) sheep.deepClone(); // 属性值相同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); // 对象的地址不同 System.out.println("sheep.hashCode:" + sheep.hashCode()); System.out.println("sheep2.hashCode:" + sheep2.hashCode()); // 引用数据类型成员变量的地址也不相同 System.out.println("sheep.friend:" + sheep.getFriend().hashCode()); System.out.println("sheep2.friend:" + sheep2.getFriend().hashCode()); 

版权声明


相关文章:

  • 软件测试面试常见问题及答案2025-07-24 18:30:12
  • elementui按钮loading2025-07-24 18:30:12
  • 前端创建项目2025-07-24 18:30:12
  • js中get和post的区别2025-07-24 18:30:12
  • 提升产业链供应链完整性2025-07-24 18:30:12
  • 数字语音处理及matlab仿真2025-07-24 18:30:12
  • can总线是什么样子2025-07-24 18:30:12
  • matlab粒子群运动模拟2025-07-24 18:30:12
  • 原型和原形的区别2025-07-24 18:30:12
  • 基于matlab的语音信号处理与分析2025-07-24 18:30:12