最近,我遇到了一个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/

10-09 22:40