我最近遇到了一个 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 对象的状态?我希望 Character 对象根据游戏事件发生变化,而不是已经存在的 Mage 对象。 Angular 色拿起一根法杖,现在变成了可以施法的“法师”。首先想到的是在 Angular 色中拥有一个状态属性,该状态属性会根据交互而变化,并且 Angular 色以某种方式“继承”现在施放的能力并获得法力状态属性。
最佳答案
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/