装饰者模式

老付     2018-08-24   2485   7min  

在23种设计模式中,装饰者模式在游戏开发的过程中,使用的很是频繁。因为这个设计模式,把所有的业务的逻辑封装的对应的实体类中,从而为主流程减负了。首先看下一个应用场景

装饰者模式的应用

我们都知道有一款经典游戏90坦克,这个游戏中,玩家坦克来操作坦克打击AI敌人,在没打死一个红色坦克就会掉下来一个装备,这个装备可以提升移动速度,增加攻击力。

我们首先定义玩家坦克是player对象,再定义几个特别的装备,增加速度,增加生命,增加攻击力。对于这个场景,可以定制一下几个方法:


 void addSpeed(Player player);
 void addLife(Player player);
 void addAttack(Player player);

这个方法定下来,就可以设计我们的程序,怎么设计呢? 我们可以设计一个最简单的设计,写一个静态的帮助类,代码实现如下:

public class EquipmentHelper{
	 public void addSpeed(Player player){

	 }
    public void addLife(Player player){

    }
    public  void addAttack(Player player){

    }

}

这个写完之后,我们们觉是可以实现我们的功能的?但是我们在条用的时候,是不是判断的逻辑比较多?如果类型比较多的时候,我们的系统就很难再维护了。

if(equipment is Speed){
	equipmentHelper.addSpeed(player);
}
if(equipment is Life){
	equipmentHelper.addLife(player);
}
....

这个一看,这样做问题出在哪里? 这个破坏了我们的player的对象,违反了OOP中的“对扩展开放,对修改关闭”的原则。

对于这个问题,我们可以用多态的方法进行,把需要抽象一个装备的基类,在基类中只有一个方法addProperty,然后就子类可以自己实现的装饰方法。整个装备类的实现如下:

装饰者模式

然后我们再调用的时候就省了if逻辑的判断:


public void equip(BaseEquipment equipment){
	equipment.addProperty(player);
}

我们对上面的方法在进行优化,就是我们今天说的装饰者模式。

装饰者实现流程图

装饰者模式

装饰者实现逻辑

经过上面的分析,我们可以使用代码来表示我们的设计。


public abstract class Element {
	public abstract String getEquipment();
}

public class Tank extends Element {
	@Override
	public String getEquipment() {
		return "我是一辆坦克";
	}
}

public abstract class BaseEquipment  extends Element{
 
}


public class AttackEquipment extends BaseEquipment {
	private Element element;
	public AttackEquipment(Element element){
		this.element=element;
	}
	@Override
	public String getEquipment() {
		return element.getEquipment()+",增加攻击力";
	}
}

public class SpeedEquipment extends BaseEquipment{
	private Element element;
	public SpeedEquipment(Element element){
		this.element=element;
	}
	@Override
	public String getEquipment() {
		return element.getEquipment()+",增加速度";
	}
}


public class LifeEquipment extends BaseEquipment{
	private Element element;
	public LifeEquipment(Element element){
		this.element=element;
	}
	@Override
	public String getEquipment() {
		return element.getEquipment()+",增加生命";
	}
}

在最终的调用的时候,我们需要什么装备,就可以直接使用。调用如下:

Element tank = new Tank();
tank = new LifeEquipment(tank);
tank = new AttackEquipment(tank);
tank = new SpeedEquipment(tank);
System.out.println(tank.getEquipment());

运行结果:

我是一辆坦克,增加生命,增加攻击力,增加速度

java中的装饰者模式的使用

在java 中,IO的实现逻辑就是装饰者模式 ,首先看下IO的逻辑类图:

装饰者模式

 InputStream dataStream = ClassLoader.getSystemResourceAsStream("");
 dataStream = new BufferedInputStream(dataStream);
 dataStream = new DataInputStream(dataStream);
 dataStream = new LineNumberInputStream(dataStream);

对于java中的IO缺点也有,会生成很多的小类,导致调用的时候不知道怎么去使用。知道了装饰者模式,我们就可以更好的使用IO的类。

(本文完)

作者:老付

如果觉得对您有帮助,可以下方的订阅,或者选择右侧捐赠作者,如果有问题,请在捐赠后咨询,谢谢合作

如有任何知识产权、版权问题或理论错误,还请指正。

自由转载-非商用-非衍生-保持署名,请遵循:创意共享3.0许可证

交流请加群113249828: 点击加群   或发我邮件 laofu_online@163.com