设计模式-原型模式(包含深浅拷贝的问题)

原型设计模式-Prototype

当我看到Prototype的时候,感觉特别熟悉,对,用过spring的同学都知道,配置spring bean的时候,其中有一项是scope配置,一个是Singleton一个是Prototype,对就是这个Prototype。spring这里就用到了原型设计模式
下面具体讲一下:

设计模式-原型模式(包含深浅拷贝的问题)_第1张图片
什么叫原型设计模式,通俗点就是克隆,没错就是object里的那个clone方法,假如有这么一个对象,现在怎么用一般方法实现呢:
设计模式-原型模式(包含深浅拷贝的问题)_第2张图片
对就这样,看起来很好理解,就是代码也太多了,看起来就很low

怎么用:

设计模式-原型模式(包含深浅拷贝的问题)_第3张图片
用clone方法就可以直接克隆了。 看起来很方便。
但是当用clone的时候,注意要克隆的类要实现Cloneable,不然抛异常。
而且这个方法涉及一个深浅克隆的问题,
这是什么?
深克隆就是跟原型除了长得一样,但是是两个完全不一样的对象。
浅克隆就是不仅长得一样,引用地址都一样。

举个例子,你把sheep中加一个对象,在用clone之后,前后用打印出地址看下,基本类型包含包装类型以及String是相等的,但是你加的那个对象的地址不一样,说明原生clone是浅拷贝。
要想实现深拷贝,实现方式有两种,一种是序列化 一种是重写clone

	//深拷贝 - 方式1 通过对象的序列化实现 (推荐)
	
	public Object deepClone() {
		
		//创建流对象
		ByteArrayOutputStream bos = null;
		ObjectOutputStream oos = null;
		ByteArrayInputStream bis = null;
		ObjectInputStream ois = null;
		
		try {
			
			//序列化
			bos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(bos);
			oos.writeObject(this); //当前这个对象以对象流的方式输出
			
			//反序列化
			bis = new ByteArrayInputStream(bos.toByteArray());
			ois = new ObjectInputStream(bis);
			DeepProtoType copyObj = (DeepProtoType)ois.readObject();
			
			return copyObj;
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return null;
		} finally {
			//关闭流
			try {
				bos.close();
				oos.close();
				bis.close();
				ois.close();
			} catch (Exception e2) {
				// TODO: handle exception
				System.out.println(e2.getMessage());
			}
		}
		
	}
//深拷贝 - 方式 2 使用clone 方法
	@Override
	protected Object clone() throws CloneNotSupportedException {
		
		Object deep = null;
		//这里完成对基本数据类型(属性)和String的克隆
		deep = super.clone(); 
		//对引用类型的属性,进行单独处理
		DeepProtoType deepProtoType = (DeepProtoType)deep;
		deepProtoType.deepCloneableTarget  = (DeepCloneableTarget)deepCloneableTarget.clone();
		
		// TODO Auto-generated method stub
		return deepProtoType;
	}

注意以后面试官问原生是深浅拷贝的时候可别打错了呦~

你可能感兴趣的:(java,设计模式,原型模式)