简体   繁体   English

如何重构 switch case 以从类调用方法?

[英]How can I refactor the switch case to call methods from a class?

I have a Hero class that extends the Player class, this hero can perform various actions, most of these actions are overridden from the Player class, so far so good.我有一个扩展 Player 类的 Hero 类,这个英雄可以执行各种动作,这些动作中的大部分都是从 Player 类中覆盖的,到目前为止还不错。

class Hero extends Player {
  constructor(level = 1) {
    super();
    this.level = level;
  }

  // override
  attack() {
    return 'attacking';
  }

  defend() {
    return 'defending';
  }

  walk() {
    return 'walking';
  }

  run() {
    return 'running';
  }

  fly() {
    return 'flying';
  }

  jump() {
    return 'jumping';
  }
}

module.exports = Hero

Now I need to call these actions dynamically by sending a parameter, for example, I look for a user in the database and check what the action's type is (integer), if it's 0, execute the attack() method, if it's 1, executes the defend() method.现在我需要通过发送参数来动态调用这些动作,例如,我在数据库中查找一个用户并检查该动作的类型是什么(整数),如果是0,则执行attack()方法,如果是1,执行defence()方法。 I created a switch case with all possible cases, however whenever I add a new action, I will have to modify the switch and it gets bigger and bigger.我创建了一个包含所有可能情况的 switch case,但是每当我添加一个新动作时,我都必须修改 switch 并且它变得越来越大。 How best to work with this?如何最好地处理这个问题? Knowing that I have to call these methods dynamically with a "type" parameter.知道我必须使用“类型”参数动态调用这些方法。

const hero = new Hero();
let type = 1; // this type is dynamic and comes from a database API
let result = null;
switch (type) {
    case 0:
        result = hero.attack();
        break;

    case 1:
        result = hero.defend();
        break;

    case 2:
        result = hero.walk();
        break;

    case 3:
        result = hero.run();
        break;

    case 4:
        result = hero.fly();
        break;

    case 5:
        result = hero.jump();
        break;
}

console.log(result)

You can map numbers to functions using an object, which will make it become way smaller (one line each).您可以使用对象将数字映射到函数,这将使其变得更小(每个一行)。 Here's a simplified example:这是一个简化的示例:

let actions = {
    1: attack,
    2: defend,
};

actions[type]();

In case your action types are really defined as successive integers starting from 0 then you may just use an array instead of a map;如果您的操作类型确实被定义为从 0 开始的连续整数,那么您可以只使用数组而不是映射;

var actions = [attack, defend, walk, ...],
    type    = 0;
actions[type](); // "attacking"

Instead of naming the functions as attack or fly .而不是将函数命名为attackfly you can name the function as type which you expecting from the db.您可以将函数命名为您期望从数据库中获得的type In the existing context it was integer so I have implemented using integers.在现有上下文中,它是整数,所以我使用整数来实现。

 class Hero { constructor(level = 1) { this.level = level; } 1() { return 'attacking'; } 2() { return 'defending'; } 3() { return 'walking'; } 4() { return 'running'; } 5() { return 'flying'; } jumping() { return 'jumping'; } } const hero = new Hero(); let type = 1; // this type is dynamic and comes from a database API let result = eval('hero[' + type + ']()'); console.log(result) type = 'jumping' // this type is dynamic and comes from a database API result = eval('hero.' + type + '()'); console.log(result)

let result = eval('hero[' + type + ']()'); and i have generated the function name and evaluated it's value dynamically.我已经生成了函数名称并动态评估了它的值。 these are some of the resources which might help you double dispatch and dynamic-function-names这些是一些可以帮助您双重调度动态函数名称的资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM