设计模式-原型模式

原型模式(Prototype)

浅拷贝: 能够直接拷贝其实际内容的数据类型/只支持9种,八大基本数据类型+String
浅拷贝: 只是拷贝了基本类型的属性数据过来,对于引用类型的属性,两个对象的引用类型的属性指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化 .

深拷贝: 字节码拷贝, 真正获取了一个对象的复制实体,而不是引用, 深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,常常采用序列化和反序列化的方式来实现深拷贝,注意对象都要实现Serializable序列化接口

在这里插入图片描述

下面展示一些 内联代码片

1.浅拷贝代码
package com.gupaoedu.vip.prototype.simple;
import java.util.ArrayList;
public class ConcretePrototype implements Cloneable{
	private int age;
	private String name;	
	public ArrayList<String> list = new ArrayList<String>();	
	protected Object clone() throws CloneNotSupportedException {
		ConcretePrototype prototype = null;
		try{
			prototype = (ConcretePrototype)super.clone();
			prototype.list = (ArrayList)list.clone();		
			//克隆基于字节码的
			//用反射,或者循环
		}catch(Exception e){			
		}		
		return prototype;
	}	
	//定义上100个属性
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}				
}

package com.gupaoedu.vip.prototype.simple;
import java.util.ArrayList;
import java.util.List;
public class CloneTest {		
	public static void main(String[] args) {		
		ConcretePrototype cp = new ConcretePrototype();
		cp.setAge(18);
		cp.setName("Tom");		
		//cp.list.add("Tom");		
		try {
		     //浅拷贝
			ConcretePrototype copy = (ConcretePrototype)cp.clone();			
			System.out.println(copy.list  == cp.list);
			System.out.println(copy.getAge() + "," + copy.getName() + copy.list.size());
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}		
		//就是一个现成的对象,这个对象里面有已经设置好的值
		//当我要新建一个对象,并且要给新建的对象赋值,而且赋值内容要跟之前的一模一样				
		//ConcretePrototype cp = new ConcretePrototype();
		//cp.setAge(18);		
		//ConcretePrototype copy = new ConcretePrototype();
		//copy.setAge(cp.getAge());
		//copy.setName(cp.getName());
		//用循环,用反射,确实可以的(反射性能并不高)
		//字节码复制newInstance()		
		//ConcretePrototype copy = cp;
		//ORM的时候经常用到的				
	}	
}

2.深拷贝
2.1 定义一个包含基本类型和引用类型的对象
package com.gupaoedu.vip.prototype.greatestsage;
import java.util.Date;
//猴子
public class Monkey {
	//身高
	protected int height;//基本
	//体重
	protected int weight;
	//生日
	protected Date birthday;//不是基本类型	
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}		
}

2.2 定义一个包含基本类型的对象
package com.gupaoedu.vip.prototype.greatestsage;
import java.io.Serializable;
/**
 * 金箍棒
 * @author maoxf
 *
 */
public class GoldRingedStaff implements Serializable{	
	private float height = 100; //长度
	private float diameter = 10;//直径		

	/**
	 * 金箍棒长大
	 */
	public void grow(){
		this.diameter *= 2;
		this.height *= 2;
	}	
	/**
	 * 金箍棒缩小
	 */
	public void shrink(){
		this.diameter /= 2;
		this.height /= 2;
	}	
}

2.3 深拷贝: 序列化和反序列化
package com.gupaoedu.vip.prototype.greatestsage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
/**
 * 齐天大圣
 * @author maoxf
 *
 */
public class TheGreatestSage  extends Monkey implements Cloneable,Serializable{	
	//金箍棒
	private GoldRingedStaff staff;
	//从石头缝里蹦出来
	public TheGreatestSage(){
		this.staff = new GoldRingedStaff();
		this.birthday = new Date();
		this.height = 150;
		this.weight = 30;
		System.out.println("------------------------");
	}	
	//分身技能
	public Object clone(){		
	//深度克隆
		ByteArrayOutputStream bos = null;
		ObjectOutputStream oos = null;
		ByteArrayInputStream bis = null;
		ObjectInputStream ois = null;
		try {
			//return super.clone();//默认浅克隆,只克隆八大基本数据类型和String
			//序列化
			bos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(bos);
			oos.writeObject(this);
			
			//反序列化
			bis = new ByteArrayInputStream(bos.toByteArray());
			ois = new ObjectInputStream(bis);
			TheGreatestSage copy = (TheGreatestSage)ois.readObject();
			copy.birthday = new Date();
			
			return copy;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}finally{
			try {
				bos.close();
				oos.close();
				bis.close();
				ois.close();				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	//变化
	public void change(){
		TheGreatestSage copySage = (TheGreatestSage)clone();
		System.out.println("大圣本尊生日是:" + this.getBirthday().getTime());
		System.out.println("克隆大圣的生日是:" + copySage.getBirthday().getTime());
		System.out.println("大圣本尊和克隆大圣是否为同一个对象:" + (this == copySage));
		System.out.println("大圣本尊持有的金箍棒跟克隆大圣持有金箍棒是否为同一个对象:" + (this.getStaff() == copySage.getStaff()));		System.out.println(this.height+":"+this.weight+this.birthday+":"+this.getStaff()+"---------"+copySage.height+":"+copySage.weight+":"+copySage.birthday+":"+copySage.getStaff());
	}
		
	public GoldRingedStaff getStaff() {
		return staff;
	}
	public void setStaff(GoldRingedStaff staff) {
		this.staff = staff;
	}	
}

2.4 测试类
package com.gupaoedu.vip.prototype.greatestsage;
public class TestPrototype {
	public static void main(String[] args) {
		TheGreatestSage sage = new TheGreatestSage();
		sage.change();
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值