理解设计模式(十)——装饰模式

装饰模式

提出问题

假设这样一种场景:在LOL中,英雄初始状态下没有任何加成(Buff)。随着游戏的推进,英雄陆续获得了红Buff和蓝Buff。那么在游戏编程中,如何体现这样的变化?

解决问题

由于英雄获得了Buff,他的一些数值就要在原有基础上发生变化。如果我们直接去修改英雄的数值是否可行?这样一来我们需要为每个英雄都实现一个获得Buff后的修改数值的函数,较为繁琐。

既然为每个英雄都增加一个修改数值的函数较为繁琐,那么能不能设计一个静态函数,它接受一个角色对象作为参数,将角色对象数值修改后返回一个新的角色对象呢?答案是肯定的。而且在我看来,这就是装饰模式的一个变种。

一般的装饰模式,都是使用一个装饰类,通过修改方法调用的方式来实现的,我们这里使用静态函数直接修改属性值来实现。本质上是一样的。

下面还是使用代码来举个🌰。我会同时写出静态函数和装饰类两种方法。

// 原始对象
class Player {
constructor(life, attack, shield, magic) {
this.life = life; // 生命值
this.attack = attack; // 攻击力
this.shield = shield; // 防御值
this.magic = magic; // 魔力值
}

startAttack() {}
}
// 使用静态函数
function BlueBuff(player) {
player = JSON.parse(JSON.stringify(player));
player.magic += 100;
return player;
}

function RedBuff(player) {
player = JSON.parse(JSON.stringify(player));
player.attack += 100;
return player;
}

let normalPlayer = new Player();
let blueBuffedPlayer = BlueBuff(normalPlayer);
let redBlueBuffedPlayer = RedBuff(blueBuffedPlayer);
redBlueBuffedPlayer.startAttack();

// 使用装饰类
class RedBuff {
constructor(player) {
this.player = player;
}

startAttack() {
player.startAttack();
moreAttack();
}
}

class BlueBuff {
constructor(player) {
this.player = player;
}

startAttack() {
player.startAttack();
moreAttack();
}
}

let normalPlayer = new Player();
let blueBuffedPlayer = new BlueBuff(normalPlayer);
let redBlueBuffedPlayer = new RedBuff(blueBuffedPlayer);
redBlueBuffedPlayer.startAttack();
Author: LeoB_O
Link: https://leob-o.github.io/2019/06/07/DecoratorPattern/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.