在暗黑破坏神等RPG游戏中,会遇到如下的一些场景:我有一把很普通的武器,我通过给它“注入魔法力量”、“镶嵌宝石”,来使得它拥有一些攻击特效:例如,一把普通长剑,镶嵌红宝石后,可以附带火焰伤害,镶嵌了一个蓝宝石后,可以使得长剑攻击带有冰冻伤害。
如何实现上述的机制呢?首先我们想到的是继承,因为,一个镶嵌了红宝石、蓝宝石的长剑,一定是一个镶嵌了宝石的长剑,并且一定一把长剑。如此下来,程序的结构会很复杂,而且你可能会想,要是镶嵌的是别的宝石怎么办呢?如果出了宝石外,可以镶嵌其他物品(如符文),那是不是应该把继承的结构改变呢?可见,继承并不是一个最优的方案。
仔细分析一下这种情况,我们会发现,所谓“火焰伤害”、“冰冻伤害”,只是一些“攻击特效”,说白了就是长剑的攻击的装饰。我们仅仅是为了能够在长剑攻击的时候,增加一些职责:触发火焰伤害、触发冰冻伤害。这个时候我们就可以用到装饰(Decorator)模式——它的意图是动态地给一个对象添加一些额外的职责。就增加新功能来说,它比继承更为灵活。
假设我想给我的长剑赋予眩晕、暴击和中毒攻击三种特效,那么Java代码可以这样写:
interface Weapon{
void printInfo();
}
class Sword implements Weapon {
public void printInfo(){
System.out.println ("一把长剑");
}
}
abstract class WeaponDecorator implements Weapon {
public Weapon weapon;
public WeaponDecorator(Weapon _weapon){
weapon = _weapon;
}
public void printInfo(){
weapon.printInfo();
}
}
class PoisonDecorator extends WeaponDecorator {
public PoisonDecorator(Weapon _weapon) {
super(_weapon);
}
public void printInfo() {
weapon.printInfo();
//以下是自己添加的方法(装饰)
System.out.println(" 有50%几率造成敌人中毒");
}
}
class CriticalDecorator extends WeaponDecorator {
public CriticalDecorator(Weapon _weapon) {
super(_weapon);
}
public void printInfo() {
weapon.printInfo();
//以下是自己添加的方法(装饰)
System.out.println(" 有50%几率造成致命一击");
}
}
class DazzleDecorator extends WeaponDecorator {
public DazzleDecorator(Weapon _weapon) {
super(_weapon);
}
public void printInfo() {
weapon.printInfo();
//以下是自己添加的方法(装饰)
System.out.println(" 有50%几率造成敌人眩晕");
}
}
class Decorator
{
public static void main(String[] args) {
Weapon superWeapon = new DazzleDecorator(new CriticalDecorator(new PoisonDecorator(new Sword())));
superWeapon.printInfo();
}
}一把长剑
有50%几率造成敌人中毒
有50%几率造成致命一击
有50%几率造成敌人眩晕
装饰模式比继承模式更加灵活(可以灵活添加职责),然而,我们必须要为每一个被装饰的方法新建一个类,如果需要装饰的方法很多,那么我们会需要建立数量巨大的装饰器类,这个时候就要考虑是否要用装饰模式了。在Java.IO,C#的IO(如OutputStream)中就用到了装饰器这种模式。需要注意到是,装饰器类必须要与被装饰的类继承于同一接口,这就如最开始所说的,不管长剑镶嵌了什么,它总是一把武器。
Java设计模式之再从[暗黑破坏神"装备镶嵌宝石系统"]分析装饰(Decorator)模式,布布扣,bubuko.com
Java设计模式之再从[暗黑破坏神"装备镶嵌宝石系统"]分析装饰(Decorator)模式
原文:http://blog.csdn.net/froser/article/details/23210377