原型模式(prototype)

原型模式(prototype

通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。

就是java的克隆技术,以某个对象为原型,复制出新的对象。显然新的对象具备原型对象的特点。

优势:效率高(直接克隆,避免了重新执行构造过程步聚)。

克隆类似于new,但是不同于new。New创建新的对象属性采用的默认值。克隆出的对象属性值的原型对象相同。并且克隆出的新对象改变不会影响原型对象。然后在修改克隆对象的值。

原型模式的实现:

Cloneable接口和Clone方法。

Prototype模式中实现起来最困难的地方就是内存复制操作,所幸java中提供了clone()方法替我们做了绝大部他事情。

注意用词:克隆和拷贝是一回事。

 

浅克隆

publicclass User implements Cloneable {

   private String name;

   private Date birthday;

 

   public String getName() {

      returnname;

   }

 

   publicvoid setName(String name) {

      this.name = name;

   }

 

   public Date getBirthday() {

      returnbirthday;

   }

 

   publicvoid setBirthday(Date birthday) {

      this.birthday = birthday;

   }

 

   public User() {

   }

 

   @Override

   protected Object clone() {

      Object obj;

      try {

          obj = super.clone();

          return obj;

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      returnnull;

   }

}

publicclass Main {

   publicstaticvoid main(String[] args) {

      Date date = new Date(1234L);

      User user1 = new User();

      user1.setName("Lucy");

      user1.setBirthday(date);

      System.out.println(user1.getName());

      System.out.println(user1.getBirthday());

     

      //修改时间。

      date.setTime(13145656789L);

      user1.setBirthday(date);

      System.out.println(user1.getBirthday());

     

      //调用克隆方法复制类

      User user2 = (User) user1.clone();

      System.out.println(user2.getName());

      System.out.println(user2.getBirthday());  

   }

}

 

输出结果:

Lucy

Thu Jan 01 08:00:01 CST 1970

Tue Jun 02 11:34:16 CST 1970

Lucy

Tue Jun 02 11:34:16 CST 1970

 

 

深克隆

publicclass User implements Cloneable {

   private String name;

   private Date birthday;

   public String getName() {

      returnname;

   }

   publicvoid setName(String name) {

      this.name = name;

   }

   public Date getBirthday() {

      returnbirthday;

   }

   publicvoid setBirthday(Date birthday) {

      this.birthday = birthday;

   }

   public User() {

   }

   @Override

   public Object clone() {

      Object obj;

      try {

          obj = super.clone();

          //添加如下代码,进行深克隆。

          User user2 = (User) obj;

          //克隆一个类的属性。

          user2.birthday = (Date) this.birthday.clone();

          return obj;

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      returnnull;

   }

}

publicclass Main {

   publicstaticvoid main(String[] args) {

      Date date = new Date(1234L);

      User user1 = new User();

      //调用克隆方法复制类

      user1.setName("Lucy");

      user1.setBirthday(date);

      User user2 = (User) user1.clone();

      System.out.println(user1.getName());

      System.out.println(user1.getBirthday());

     

      //修改时间。

      date.setTime(13145656789L);

      user1.setBirthday(date);

      System.out.println("user1的生日:"+user1.getBirthday());

      user2.setName("Rows");

      System.out.println(user2.getName());

      System.out.println("user2的生日:"+user2.getBirthday()); 

   }

}

输出结果:

Lucy

Thu Jan 01 08:00:01 CST 1970

user1的生日:Tue Jun 02 11:34:16 CST 1970

Rows

user2的生日:Thu Jan 01 08:00:01 CST 1970

开发中的应用场景:

原型模式很少出现,一般是和工厂方法一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。

Spring中的bean的创建实际上就是两种:单例模式和原型模式。(当然,原型模式需要和工厂模式搭配起来)。

 

利用序列化和反序列化技术实现深克隆

publicstaticvoid main(String[] args) throws Exception {

      Date date = new Date(1234L);

      User user1 = new User();

      // 调用克隆方法复制类

      user1.setName("Lucy");

      user1.setBirthday(date);

      User user2 = (User) user1.clone();

     

      // 通过序列化和反序列化深复制对象

      ByteArrayOutputStream bos = new ByteArrayOutputStream();

      ObjectOutputStream oos = new ObjectOutputStream(bos);

      oos.writeObject(user1);

      byte[] by = bos.toByteArray();

        //反序列化

      ByteArrayInputStream bin = new ByteArrayInputStream(by);

      ObjectInputStream ois = new ObjectInputStream(bin);

      User user3 = (User) ois.readObject();

 

      System.out.println(user1.getName());

      System.out.println(user1.getBirthday());

 

      // 修改时间。

      date.setTime(13145656789L);

      user1.setBirthday(date);

      System.out.println("user1的生日:" + user1.getBirthday());

      user2.setName("Rows");

      System.out.println(user2.getName());

      System.out.println("user2的生日:" + user2.getBirthday());

 

      System.out.println(user3.getName());

      System.out.println("user3的生日:" + user3.getBirthday());

   }

输出内容

Lucy

Thu Jan 01 08:00:01 CST 1970

user1的生日:Tue Jun 02 11:34:16 CST 1970

Rows

user2的生日:Thu Jan 01 08:00:01 CST 1970

Lucy

user3的生日:Thu Jan 01 08:00:01 CST 1970

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值