【问题标题】:How do you refactor a big chunk of conditionals?你如何重构大量的条件语句?
【发布时间】:2014-06-18 17:01:41
【问题描述】:

我正在制作一个玩家可以点击操作按钮的游戏。此操作按钮将根据上下文执行完全不同的操作。

function doAction() {
    if (standingOnItem) {
        if (itemOnGround === POTION) {
            if (equippiedItem === POTION) {
                // mix potions
                return;
            }

            if (equippiedItem === TORCH) {
                // boil potion
                return;
            }

            // pick up potion
        }

        if (itemOnGround === CHEST && equippedItem === KEY) {
            // open chest
        }

        return;
    }

    if (equippedItem === POTION) {
        // put potion on the ground
    }

    if (equippedItem === TORCH) {
        // put out torch and drop it on the ground
    }

    if (standingOnStaircase && equippedItem === KEY) {
        // move down one level
    }
}

以上只是示例代码,但在我的游戏中,doAction 函数已经包含 50 个或更多条件。仅仅知道以什么顺序放置它们已成为我添加的每一个新事物的问题。问题是所有不同的组合或多或少都有独特的作用。

如何以更好的方式重构它?我可以使用任何特定的设计模式吗?

【问题讨论】:

标签: javascript refactoring conditional conditional-statements


【解决方案1】:

您似乎可以根据某些顶级决策将其分解为单独的功能,在这种情况下,就像用户站立的位置一样。

function doAction() {
    if (standingOnGround) {
        doOnGroundAction();
    } else if (standingOnItem) {
        doOnItemAction();
    } else {
        doBasicAction();
    }
}

然后,您可以根据其他变量获得操作图:

// Map of item on the ground and item equipped. 
var groundActions = {
    POTION: {
        POTION: function () {},
        TORCH: function () {} 
    },
    CHEST: {
        KEY: function () { 
            // open chest.
        }
    }
};

function doGroundAction() {
    // If there is an action defined in the map execute it, otherwise 
    // perform some default action.
    if (groundActions[itemOnGround] && groundActions[itemOnGround][equippedItem]) {
        groundActions[itemOnGround][equippedItem]();
    } else {
        // Some default action.
    }
}

【讨论】:

    【解决方案2】:

    有几种方法可以解决这个问题。

    当您只测试一个条件时,switch 语句是正常的...

    switch (action) {
      case "drop":
      // handle drop
      break;
      case "get":
      // Handle get
      break;
    };
    

    也就是说,我真的更喜欢使用 JavaScript 对象而不是 switch 语句。我认为它们更干净。

    var actions = {
      get: function(obj) {
        // handle get
      },
      drop: function(obj) {
        // handle drop
      }
    };
    
    var verb="get";
    action[verb](obj);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-16
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 2013-07-03
      • 2021-12-30
      • 1970-01-01
      相关资源
      最近更新 更多