如何重构 switch case 以从 class 调用方法?
How can I refactor the switch case to call methods from a class?
我有一个扩展玩家 class 的英雄 class,这个英雄可以执行各种动作,这些动作中的大部分都被玩家 class 覆盖了,到目前为止还不错.
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
现在我需要通过发送参数来动态调用这些动作,例如,我在数据库中查找用户并检查动作的类型是什么(整数),如果是0,则执行attack()方法,如果为1,则执行defend()方法。我创建了一个包含所有可能情况的 switch case,但是每当我添加一个新动作时,我都必须修改 switch,它会变得越来越大。如何最好地使用它?知道我必须使用“类型”参数动态调用这些方法。
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)
您可以使用对象将数字映射到函数,这将使它变得更小(每行一行)。这是一个简化的例子:
let actions = {
1: attack,
2: defend,
};
actions[type]();
而不是将函数命名为 attack
或 fly
。您可以将该函数命名为 type
您期望从数据库中获得的名称。在现有的背景下
它是整数,所以我使用整数来实现。
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 + ']()');
并且我生成了函数名称并动态评估了它的值。这些资源可能会对您有所帮助 double dispatch and dynamic-function-names
如果您的操作类型确实定义为从 0 开始的连续整数,那么您可以只使用数组而不是映射;
var actions = [attack, defend, walk, ...],
type = 0;
actions[type](); // "attacking"
我有一个扩展玩家 class 的英雄 class,这个英雄可以执行各种动作,这些动作中的大部分都被玩家 class 覆盖了,到目前为止还不错.
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
现在我需要通过发送参数来动态调用这些动作,例如,我在数据库中查找用户并检查动作的类型是什么(整数),如果是0,则执行attack()方法,如果为1,则执行defend()方法。我创建了一个包含所有可能情况的 switch case,但是每当我添加一个新动作时,我都必须修改 switch,它会变得越来越大。如何最好地使用它?知道我必须使用“类型”参数动态调用这些方法。
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)
您可以使用对象将数字映射到函数,这将使它变得更小(每行一行)。这是一个简化的例子:
let actions = {
1: attack,
2: defend,
};
actions[type]();
而不是将函数命名为 attack
或 fly
。您可以将该函数命名为 type
您期望从数据库中获得的名称。在现有的背景下
它是整数,所以我使用整数来实现。
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 + ']()');
并且我生成了函数名称并动态评估了它的值。这些资源可能会对您有所帮助 double dispatch and dynamic-function-names
如果您的操作类型确实定义为从 0 开始的连续整数,那么您可以只使用数组而不是映射;
var actions = [attack, defend, walk, ...],
type = 0;
actions[type](); // "attacking"