最近,我遇到了一个great article,涵盖了对象组合与传统继承相比的优势。
希望我的问题不会被标记为“自以为是”,但是我想知道一种很好的方法,当对象根据用户的游戏交互而改变时,使用合成。
以文章代码为例:
const canCast = (state) => ({
cast: (spell) => {
console.log(`${state.name} casts ${spell}!`);
state.mana--;
}
})
const canFight = (state) => ({
fight: () => {
console.log(`${state.name} slashes at the foe!`);
state.stamina--;
}
})
const fighter = (name) => {
let state = {
name,
health: 100,
stamina: 100
}
return Object.assign(state, canFight(state));
}
const mage = (name) => {
let state = {
name,
health: 100,
mana: 100
}
return Object.assign(state, canCast(state));
}
scorcher = mage('Scorcher')
scorcher.cast('fireball'); // Scorcher casts fireball!
console.log(scorcher.mana) // 99
slasher = fighter('Slasher')
slasher.fight(); // Slasher slashes at the foe!
console.log(slasher.stamina) // 99
如何在运行时使用合成来更改Character对象的状态?而不是已经存在的Mage对象,我希望Character对象根据游戏事件进行更改,例如。角色拾起一支法杖,现在成为可以施放咒语的“法师”。首先想到的是在角色中具有状态属性,该属性会根据交互作用而发生变化,并且角色会以某种方式“继承”现在施法并获得法力状态属性的能力。
最佳答案
decorator pattern完全可以解决这种情况。
class Character {
constructor(name) {
this.name = name;
this.health = 100;
this.items = [];
}
}
const fighterDecorator = character => {
return Object.setPrototypeOf({
character,
stamina: 100,
fight() {
console.log(`${this.name} slashes at the foe!`);
this.stamina--;
}
}, character);
}
const mageDecorator = character => {
return Object.setPrototypeOf({
character,
mana: 100,
cast(spell) {
console.log(`${this.name} casts ${spell}!`);
this.mana--;
}
}, character);
}
let character = new Character("Bob");
// Can't fight; can't cast
// character.fight(); // TypeError: not a function
// character.cast(); // TypeError: not a function
// Character becomes a fighter at runtime
// Equiping an item and decorating new behavior are separate statements
character.items.push("sword");
character = fighterDecorator(character);
character.fight(); // Bob slashes at the foe!
console.log(character.stamina) // 99
console.log(character.items) // ["sword"]
// Character becomes normal unit again
// Remove decoration and remove item
character = character.character;
character.items = character.items.filter(item => item !== "sword");
// Once again, can't fight, can't cast
// character.fight(); // TypeError: not a function
// character.cast(); // TypeError: not a function
// Character becomes a mage at runtime
// Equiping an item and decorating new behavior are separate statements
character.items.push("staff");
character = mageDecorator(character);
character.cast("fireball"); // Bob casts fireball!
console.log(character.mana) // 99
console.log(character.items) // ["staff"]
关于javascript - 功能 “real-time”组成,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50844719/