原型设计模式

原型设计模式


  1. 简单介绍

    原型设计模式是一种创建型设计模式。通过原型实例对象创建与该实例相同类型的对象实例,且将原型(可以简单理解为成员属性)拷贝给新创建的对象实例。

  2. 使用场景

    需要创建与某个实例对象具有相同状态(成员变量值相同)的对象。

  3. 场景举例

    Spring获取Bean对象时,其中一种方式采用了原型设计模式。通过配置scope属性为prototype来指定创建原型对象。

  4. UML类图

    原型设计模式UML类图

  5. 拷贝方式

    • 浅拷贝

      对于基本数据类型的成员变量,浅拷贝直接进行值传递,而对于引用数据类型的成员变量,浅拷贝则只进行引用的传递

    • 深拷贝

      对于基本数据类型的成员变量,深拷贝直接进行值传递,而对于引用数据类型的成员变量,深拷贝为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直至该对象可达的所有对象。

  6. 具体实现

    模拟简历的拷贝,其中简历类(Resume)所依赖引用数据类型为头像类(Photo)

    • 浅拷贝

      /**
       * 头像照片类,被简历类(Resume)所依赖的应用数据类型
       */
      public class Photo {
      
          private Integer height;
      
          private Integer Width;
          
          // get和set方法省略
      }
      
      /**
       * 简历类,通过重写Object中的clone()方法来实现
       */
      public class Resume implements Cloneable {
      
          private String name;
      
          private Integer age;
      
          private Double weight;
      
          /**
           * 引用数据类型,用来表示简历上的头像照片
           */
          private Photo photo;
          
          /**
           * 通过调用父类Object中的clone()方法完成简历对象的浅拷贝
           */
          @Override
          protected Object clone() throws CloneNotSupportedException {
              return super.clone();
          }
          
          // get和set方法省略
      }
      
    • 深拷贝(方式一:重写引用数据类型的clone()方法)

      /**
       * 头像照片类,被简历类(Resume)所依赖的应用数据类型
       */
      public class Photo implements Cloneable {
      
          private Integer height;
      
          private Integer Width;
          
          /**
           * 重写clone()方法
           */
          @Override
          protected Object clone() throws CloneNotSupportedException {
              return super.clone();
          }
          // get和set方法省略
      }
      
      /**
       * 简历类,通过重写Object中的clone()方法来实现
       */
      public class Resume implements Cloneable {
      
          private String name;
      
          private Integer age;
      
          private Double weight;
      
          /**
           * 引用数据类型,用来表示简历上的头像照片
           */
          private Photo photo;
          
          /**
           * 通过调用父类Object中的clone()方法完成简历对象的浅拷贝
           */
          @Override
          protected Object clone() throws CloneNotSupportedException {
              Resume resumeClone = (Resume) super.clone();
              // 对Resume实例对象中的引用数据类型进行拷贝对象的复制,从而达到深拷贝
              resumeClone.setPhoto((Photo) resumeClone.getPhoto().clone());
              return resumeClone;
          }
          
          // get和set方法省略
      }
      
    • 深拷贝(序列化)

      /**
       * 头像照片类,被简历类(Resume)所依赖的应用数据类型
       */
      public class Photo implements Serializable {
      
          private Integer height;
      
          private Integer Width;
         
          // get和set方法省略
      }
      
      /**
       * 简历类,通过序列化的方法来完成深拷贝(推荐)
       */
      public class Resume implements Serializable {
      
          private String name;
      
          private Integer age;
      
          private Double weight;
      
          private Photo photo;
      
          public Object deepCopy() throws Exception {
      
              // 序列化
              ByteArrayOutputStream bos;
              ObjectOutputStream oos;
              bos = new ByteArrayOutputStream();
              oos = new ObjectOutputStream(bos);
              oos.writeObject(this);
      
              // 反序列化
              ByteArrayInputStream bis;
              ObjectInputStream ois;
              bis = new ByteArrayInputStream(bos.toByteArray());
              ois = new ObjectInputStream(bis);
      
              // 关流操作省略
              
              return ois.readObject();
          }
      }
      
  7. 源码展示

    • JDK中的实现了Cloneable接口的类,都采用了原型设计模式来获取实例对象,如常用的容器类ArrayList等

      public class ArrayList<E> implements Cloneable {
          public Object clone() {
              try {
                  // 重写类clone()方法,实现了深拷贝,容器元素都是独立的
                  ArrayList<?> v = (ArrayList<?>) super.clone();
                  v.elementData = Arrays.copyOf(elementData, size);
                  v.modCount = 0;
                  return v;
         } catch (CloneNotSupportedException e) {
                  // this shouldn't happen, since we are Cloneable
                  throw new InternalError(e);
              }
          }
      }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值