设计模式之原型模式

总体来说设计模式分为三大类:
创建型模式5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

原型模式

将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象
浅复制:将一个对象复制后,基本数据类型和String的变量都会重新创建,而引用类型除String外,指向的还是原对象所指向的。
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

Demo

浅复制

首先创建一个实体类
public class Prototype{
 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 } 

}
其次,创建一个包含实体的实体类
public class NewPrototype implements Cloneable {

 private String id;
 private Prototype prototype;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public Prototype getPrototype() {
  return prototype;
 }

 public void setPrototype(Prototype prototype) {
  this.prototype = prototype;
 }


 public Object clone(){ 
  try {
   return super.clone();
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
   return null;
  }  
 }

}
然后,编写测试类
public class TestMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  testPrototype();
 }

 private static void testPrototype(){
  Prototype pro = new Prototype();
  pro.setName("original object");
  NewPrototype newObj = new NewPrototype();
  newObj.setId("test1");
  newObj.setPrototype(pro);

  NewPrototype copyObj = (NewPrototype)newObj.clone();
  copyObj.setId("testCopy");
  copyObj.getPrototype().setName("changed object");

  System.out.println("original object id:" + newObj.getId());
  System.out.println("original object name:" + newObj.getPrototype().getName());

  System.out.println("cloned object id:" + copyObj.getId());
  System.out.println("cloned object name:" + copyObj.getPrototype().getName());

 }
}
最后,看输出结果


original object id:test1
original object name:changed object
cloned object id:testCopy
cloned object name:changed object


深复制

首先创建一个实体类
public class Prototype implements Cloneable {
 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Object clone() {
  try { 
   return super.clone();
  } catch (CloneNotSupportedException e) {   
   e.printStackTrace();
   return null;
  }
 } 

}
其次,创建一个包含实体的实体类
方式一:
public class NewPrototype implements Cloneable {

 private String id;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 private Prototype prototype;

 public Prototype getPrototype() {
  return prototype;
 }

 public void setPrototype(Prototype prototype) {
  this.prototype = prototype;
 }


 public Object clone(){
  NewPrototype ret = null;
  try {
   ret = (NewPrototype)super.clone();
   ret.prototype = (Prototype)this.prototype.clone();//关键代码
   return ret;
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
   return null;
  }  
 }

}
方式二:
public class PrototypeSe implements Serializable {

 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

public class NewPrototypeSe implements Serializable {

 private String id;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 private PrototypeSe prototype;

 public PrototypeSe getPrototype() {
  return prototype;
 }

 public void setPrototype(PrototypeSe prototype) {
  this.prototype = prototype;
 }

 public Object deepClone(){
  try {
  //采用流的方式进行读入输出来创建新对象
   ByteArrayOutputStream bo = new ByteArrayOutputStream();
   ObjectOutputStream oo = new ObjectOutputStream(bo);   
   oo.writeObject(this);   

   ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
   ObjectInputStream oi = new ObjectInputStream(bi);
   return oi.readObject(); 
  } catch (IOException | ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   return null;
  }
 }

}
然后,编写测试类
public class TestMain {

 public static void main(String[] args) {
  testDeepCopy();
 }

 private static void testDeepCopy(){
  Prototype pro = new Prototype();
  pro.setName("original object");
  NewPrototype newObj = new NewPrototype();
  newObj.setId("test1");
  newObj.setPrototype(pro);

  NewPrototype copyObj = (NewPrototype)newObj.clone();
  copyObj.setId("testCopy");
  copyObj.getPrototype().setName("changed object");

  System.out.println("original object id:" + newObj.getId());
  System.out.println("original object name:" + newObj.getPrototype().getName());

  System.out.println("cloned object id:" + copyObj.getId());
  System.out.println("cloned object name:" + copyObj.getPrototype().getName());

 }

}
最后,查看输出结果


original object id:test1
original object name:original object
cloned object id:testCopy
cloned object name:changed object

总结

一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可以改成任意的名称,因为Cloneable接口是个空接口,你可以任意定义实现类的方法名,如cloneA或者cloneB,因为此处的重点是super.clone()这句话,super.clone()调用的是Object的clone()方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值