我学设计模式之原型模式

一、Protype模式简介
原型模式的特点为对象通过复制自己进行创建生成新对象,是一种对象创建型模式。
特点:
1、由原型对象自身创建目标对象(意味着具体原型类需要实现cloneable接口)。
2、目标对象是原型对象的一个克隆。通过Prottype模式创建的对象,不仅仅与目标对象具有相同的结构,还与目标对象具有相同的值。
3、根据对象克隆层次的不同,有浅克隆与深克隆。
二、实例角度介绍:
假如有一个游戏角色剑圣,剑圣有影分身技能,影分身也能分裂成多个影分身。
原型接口

   public interface Blademaster{

	Blademaster clone();
}

具体原型类

public class BlademasterShadow implements Blademaster,Cloneable,Serializable{
	int damage;
	String speed;
	String skill;
	int blood;
	int armor;
	ShadowOfShowdow shadow;
	boolean isDeepClone;
	BlademasterShadow(int damage,String speed,String skill,int blood,int armor,ShadowOfShowdow shadow,boolean isDeepClone) {
		this.armor = armor;
		this.blood = blood;
		this.damage = damage;
		this.skill = skill;
		this.speed = speed;
		this.shadow = shadow;
		this.isDeepClone = isDeepClone;
	}
	public int getDamage() {
		return damage;
	}
	public void setDamage(int damage) {
		this.damage = damage;
	}
	public String getSpeed() {
		return speed;
	}
	public void setSpeed(String speed) {
		this.speed = speed;
	}
	public String getSkill() {
		return skill;
	}
	public void setSkill(String skill) {
		this.skill = skill;
	}
	public int getBlood() {
		return blood;
	}
	public void setBlood(int blood) {
		this.blood = blood;
	}
	public int getArmor() {
		return armor;
	}
	
	public void setArmor(int armor) {
		this.armor = armor;
	}
	
	
	
	public ShadowOfShowdow getShadow() {
		return shadow;
	}
	public void setShadow(ShadowOfShowdow shadow) {
		this.shadow = shadow;
	}
	public boolean isDeepClone() {
		return isDeepClone;
	}
	public void setDeepClone(boolean isDeepClone) {
		this.isDeepClone = isDeepClone;
	}
	public void Resume() {
		System.out.println("damage:" + this.damage+'\n'+
				"speed:" + this.speed+'\n'+
				"skill:" + this.skill+'\n'+ 
				"blood:" + this.blood+'\n'+
				"armor:" + this.armor +'\n'+ "*******************");
	}
	@Override
	public BlademasterShadow clone(){
		if(isDeepClone) {
			return deepClone();
		}
		else {
			return shallowClone();
		}
	}
	
	private BlademasterShadow shallowClone() {
		
		try {
			return 	 (BlademasterShadow) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	private BlademasterShadow deepClone() {
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bos);
			oos.writeObject(this);
			ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bis);
			bis.close();
			ois.close();
			BlademasterShadow blademasterShadow = (BlademasterShadow) ois.readObject();
			return blademasterShadow;
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
}


class ShadowOfShowdow implements Serializable{
	String whoseShadow;
	ShadowOfShowdow(String whoseShadow){
		this.whoseShadow = whoseShadow;
	}
	public String getWhoseShadow() {
		return whoseShadow;
	}
	public void setWhoseShadow(String whoseShadow) {
		this.whoseShadow = whoseShadow;
	}
	
}

客户端测试类

public class CloneTest {
	
	public static void main(String[] args) {
		ShadowOfShowdow shadow1 = new ShadowOfShowdow("影分身1");
		BlademasterShadow shadowA = new BlademasterShadow(100,"100m/s","剑刃风暴",1000,500,shadow1,true);
		BlademasterShadow shadowB = shadowA.clone();
		//clone生成的对象实例单独开辟空间
		System.out.println("deepclone下shadowA == shadowB?" + (shadowA == shadowB));
		System.out.println("deepclone下shadowASkill==shadowBSkill?" + (shadowA.getSkill() == shadowB.getSkill()));
		System.out.println("deepclone下shadowA's shadow==shadowB's shadow?" +(shadowA.getShadow()==shadowB.getShadow()));
		shadowA.getShadow().setWhoseShadow("影分身2");
		shadowA.setSkill("平A");
		shadowA.setDeepClone(false);
		BlademasterShadow shadowC  =shadowA.clone();
		System.out.println("shallowClone下shadowA == shadowB?" +(shadowA==shadowC));
		//浅克隆只克隆对象里边的基础类型变量,对于引用类型只clone了引用,未开辟新的空间
		System.out.println("shallowClone下shadowASkill==shadowBSkill?" + (shadowA.getSkill() == shadowC.getSkill()));
		System.out.println("shallowClone下shadowA's shadow==shadowB's shadow?" +(shadowA.getShadow()==shadowC.getShadow()));
		shadowA.getShadow().setWhoseShadow("影分身3");
		shadowA.Resume();
		shadowB.Resume();
		shadowC.Resume();
		System.out.println(shadowA.getShadow().getWhoseShadow());
		System.out.println(shadowB.getShadow().getWhoseShadow());
		System.out.println(shadowC.getShadow().getWhoseShadow());
	}
}

执行结果:
运行结果

三、实例结果分析
从结果中,我们可以看到,deepclone和shallowclone都是都完整复制了原型类对象shadowA的结构,此处通过序列化生成对象的方式实现deepclone(当然也可以通过对应用类型的单独clone来实现),deepclone下所有成员地址对比都返回false,这意味着clone出来的对象shadowB与原型对象shadowA完全不关联,在这种情况下算是彻底的克隆了。再看shallowclone,其引用类型的地址对比返回结果都为true,这意味着shadowA与shadowC下的引用类型变量指向的是同一个内存地址,后边我们对shadowA的whoseshadow进行赋值,shadowC的whoseshadow也跟着改变了,但shadowB完全不受影响,这一现象也印证了前边的结论。

总结:
优点:
1、原型模式是创建型模式,其通过克隆的方式进行对象创建的效率比new的方式高(由于clone方法是有虚拟机直接复制内存块执行,所以在速度上比使用new的方式创建对象要快。)
2、当创建的对象实例较为复杂的时候或者创建对象比较损耗性能时,使用原型模式可以简化对象创建的过程,提高性能。

缺点:
实现深度克隆时需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用的时候,为了实现深度克隆,每一层对象的类都必须支持深度克隆,较为繁琐。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值