当前位置:   article > 正文

设计模式三(原型模式)

设计模式三(原型模式)

在开发过程中,创建多个数据相同的对象,每次new都开销比较大,在这里可以使用对象克隆,以先创建的原型对象为模板进行对象的复制。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用

浅克隆

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址

 
  1. public class Person implements  Cloneable{
  2.  ​
  3.       int num;
  4.       String name;
  5.  ​
  6.      public Person() {
  7.     }
  8.  ​
  9.      public Person(int num, String name) {
  10.          this.num = num;
  11.          this.name = name;
  12.     }
  13.  ​
  14.      public int getNum() {
  15.          return num;
  16.     }
  17.  ​
  18.      public void setNum(int num) {
  19.          this.num = num;
  20.     }
  21.  ​
  22.      public String getName() {
  23.          return name;
  24.     }
  25.  ​
  26.      public void setName(String name) {
  27.          this.name = name;
  28.     }
  29.  ​
  30.  ​
  31.  ​
  32.      @Override
  33.      protected Person clone() throws CloneNotSupportedException {
  34.          Person person = (Person)super.clone();
  35.          return person;
  36.     }
  37.  ​
  38.      @Override
  39.      public String toString() {
  40.          return "Person{" +
  41.                  "num=" + num +
  42.                  ", name='" + name + '\'' +
  43.                  '}';
  44.     }
  45.  }
  1.  public class Test {
  2.  ​
  3.      public static void main(String[] args) throws CloneNotSupportedException {
  4.  ​
  5.          Person p1 = new Person(100,"jim");
  6.          Person p2 =p1.clone();//clone方法 返回一个新对象
  7.          p2.name = "tom";
  8.          System.out.println(p1);//100 ,jim
  9.          System.out.println(p2);//100 tom
  10.  ​
  11.          System.out.println(p1==p2);//false
  12.  ​
  13.     }
  14.  }

深克隆

多层克隆

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制

  1.  public class Person implements  Cloneable{
  2.  ​
  3.       int num;
  4.       String name;
  5.       Address address;
  6.  ​
  7.      public Person() {
  8.  ​
  9.     }
  10.  ​
  11.      public Person(int num, String name) {
  12.          this.num = num;
  13.          this.name = name;
  14.     }
  15.  ​
  16.      public int getNum() {
  17.          return num;
  18.     }
  19.  ​
  20.      public void setNum(int num) {
  21.          this.num = num;
  22.     }
  23.  ​
  24.      public String getName() {
  25.          return name;
  26.     }
  27.  ​
  28.      public void setName(String name) {
  29.          this.name = name;
  30.     }
  31.  ​
  32.      public Address getAddress() {
  33.          return address;
  34.     }
  35.  ​
  36.      public void setAddress(Address address) {
  37.          this.address = address;
  38.     }
  39.  ​
  40.      @Override
  41.      protected Person clone() throws CloneNotSupportedException {
  42.          Person person = (Person)super.clone();
  43.          person.address = address.clone();   //深度复制 联同person中关联的对象也一同克隆.
  44.          return person;
  45.     }
  46.  ​
  47.      @Override
  48.      public String toString() {
  49.          return "Person{" +
  50.                  "num=" + num +
  51.                  ", name='" + name + '\'' +
  52.                  ", address=" + address +
  53.                  '}';
  54.     }
  55.  }
  56.  ​
  1.  public class Address  implements Cloneable{
  2.  ​
  3.       String  address;
  4.  ​
  5.      public String getAddress() {
  6.          return address;
  7.     }
  8.  ​
  9.      public void setAddress(String address) {
  10.          this.address = address;
  11.     }
  12.  ​
  13.      @Override
  14.      public String toString() {
  15.          return "Address{" +
  16.                  "address='" + address + '\'' +
  17.                  '}';
  18.     }
  19.  ​
  20.       @Override
  21.      protected Address clone() throws CloneNotSupportedException {
  22.          return (Address) super.clone();
  23.     }
  24.  }

序列化

 
  1. public class Address  implements Serializable {
  2.  ​
  3.       String  address;
  4.  ​
  5.      public String getAddress() {
  6.          return address;
  7.     }
  8.  ​
  9.      public void setAddress(String address) {
  10.          this.address = address;
  11.     }
  12.  ​
  13.      @Override
  14.      public String toString() {
  15.          return "Address{" +
  16.                  "address='" + address + '\'' +
  17.                  '}';
  18.     }
  19.  ​
  20.  }
 
  1. public class Person implements Serializable {
  2.  ​
  3.       int num;
  4.       String name;
  5.       Address address;
  6.  ​
  7.      public Person() {
  8.     }
  9.  ​
  10.      public Person(int num, String name) {
  11.          this.num = num;
  12.          this.name = name;
  13.     }
  14.  ​
  15.      public int getNum() {
  16.          return num;
  17.     }
  18.  ​
  19.      public void setNum(int num) {
  20.          this.num = num;
  21.     }
  22.  ​
  23.      public String getName() {
  24.          return name;
  25.     }
  26.  ​
  27.      public void setName(String name) {
  28.          this.name = name;
  29.     }
  30.  ​
  31.      public Address getAddress() {
  32.          return address;
  33.     }
  34.  ​
  35.      public void setAddress(Address address) {
  36.          this.address = address;
  37.     }
  38.  ​
  39.      /**
  40.       * 自定义克隆方法
  41.       * @return
  42.       */
  43.      public Person myclone() {
  44.              Person person = null;
  45.                try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
  46.                       ByteArrayOutputStream baos = new ByteArrayOutputStream();
  47.                        ObjectOutputStream oos = new ObjectOutputStream(baos);
  48.                        oos.writeObject(this);
  49.              // 将流序列化成对象
  50.                      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  51.                       ObjectInputStream ois = new ObjectInputStream(bais);
  52.                       person = (Person) ois.readObject();
  53.                   } catch (IOException e) {
  54.                       e.printStackTrace();
  55.                   } catch (ClassNotFoundException e) {
  56.                       e.printStackTrace();
  57.                   }
  58.               return person;
  59.           }
  60.  ​
  61.  ​
  62.      @Override
  63.      public String toString() {
  64.          return "Person{" +
  65.                  "num=" + num +
  66.                  ", name='" + name + '\'' +
  67.                  ", address=" + address +
  68.                  '}';
  69.     }
  70.  }

 练习

题目页面 (kamacoder.com)

  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) throws CloneNotSupportedException {
  4. Scanner scanner = new Scanner(System.in);
  5. int num = scanner.nextInt();
  6. while(num-->0){
  7. String color = scanner.next();
  8. int width = scanner.nextInt();
  9. int height = scanner.nextInt();
  10. Prototype prototype = new Prototype(color, width, height);
  11. Prototype clone = prototype.clone();
  12. System.out.println(clone.toString());
  13. }
  14. }
  15. }
  16. class Prototype implements Cloneable{
  17. private String color;
  18. private int width;
  19. private int height;
  20. public Prototype(String color, int width, int height) {
  21. this.color = color;
  22. this.width = width;
  23. this.height = height;
  24. }
  25. @Override
  26. public String toString() {
  27. return "Color: " + color + ", Width: " + width + ", Height: " + height;
  28. }
  29. @Override
  30. protected Prototype clone() throws CloneNotSupportedException {
  31. return (Prototype) super.clone();
  32. }
  33. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/41741
推荐阅读
相关标签
  

闽ICP备14008679号