Java 设计模式之原型模式的详解(创建模式)

原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字可以看出,该模式的思想就是将一个对象作为原型,对其进行复制,克隆,产生一个和原对象类似的新对象。

我们先来看一下原型模式的模型:


原型模型涉及到三个角色:

客户角色(client:客户端提出创建对象的请求;

抽象原型(prototype:这个往往由接口或者抽象类来担任,给出具体原型类的接口;

具体原型(Concrete prototype:实现抽象原型,是被复制的对象;

模拟代码如下:

抽象原型:

public interface Prototype extends Cloneable{

	public abstract Object clone();
}
具体原型:

public class ConcretePrototype implements Prototype{

	  @Override  
	      public Object clone() {   
	          try {   
	              return super.clone();   
	          } catch (CloneNotSupportedException e) {   
	              // TODO Auto-generated catch block  
	              e.printStackTrace();   
	              return null;   
	          }   
	             
	     }      
}
客户角色:

public class Client {

	private Prototype prototype;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Client c = new Client();
		c.prototype = c.getNewPrototype(new ConcretePrototype());

	}

	/**
	 * 
	 * @param prototype
	 * @return
	 */
	public Prototype getNewPrototype(Prototype prototype) {
		return (Prototype) prototype.clone();
	}
}

以上代码简单描述了原型模式的实现,说到这里估计很多人要跳了,因为说到原型模式不能不说的问题是java的深拷贝和浅拷贝,那下面我们就来讨论下深拷贝和浅拷贝。

浅拷贝是指拷贝引用,实际内容并没有复制,改变后者等于改变前者。

深拷贝拷贝出来的东西和被拷贝者完全独立,相互没有影响。

引用一个例子:

有一个人叫张三,人们给他取个别命叫李四,不管张三还是李四都是一个人,张三胳膊疼,李四也是一个样的不爽。这个就是浅拷贝,只是个别名而已。

同样还是有一个人叫张三,通过人体克隆技术(如果法律允许)得到一个李四,这个李四和被克隆的张三完全是两个人,张三就是少个胳膊,李四也不会感到疼痛。这个就是深拷贝。

 

java语言提供Cloneable接口,在运行时通知虚拟机可以安全的在这个类上使用clone()方法,通过这个方法可以复制一个对象,但是Object并没有实现这个接口,所以在拷贝是必须实现此标识接口,否则会抛出CloneNotSupportedException

但是clone()方法出来的默认都是浅拷贝,如果要深拷贝,那么可以考虑自己编写clone方法,但是深度很难控制,编写这个clone方法也不是最佳方案,还有个比较好的方案就是串行化来实现,代码如下:

  public Object deepClone(){   
      ByteArrayOutputStream bos = new ByteArrayOutputStream();    
      ObjectOutputStream oos = new ObjectOutputStream(bos);    
      oos.writeObject(this);    
      ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray())    
      ObjectInputStream ois = new ObjectInputStream(bis);    
      return ois.readObject();   
  }  

这样就可以实现深拷贝,前提是对象实现java.io.Serializable接口。

注意:除了基本数据类型外,其他对象默认拷贝都是浅拷贝,String类型是个例外,虽然是基本类型,但是也是浅拷贝,这个跟它实际在java内存存储情况有关。超出了设计模式讨论范围,大家可自行查看相关资料。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值