何时使用常量作为参数而不是魔术值

时间:2010-02-12 01:39:47

标签: parameters constants

我已阅读(并且普遍同意)为了提高代码易读性,您应该使用常量而不是幻数作为方法参数。例如,使用PHP:

// no constants ////////////////////
function updateRecord($id) {
    if ($id == -1) {
        // update all records
    } else {
        // update record with "id = $id"
    }
}

updateRecord(-1); // future maintainer says: "wtf does -1 do?"
                  // and then has to jump to the function definition

// with constants: /////////////////

define('UPDATE_ALL', -1);

function updateRecord($id) {
    if ($id == UPDATE_ALL) {
        // update all records
    } else {
        // update record with "id = $id"
    }
}

updateRecord(UPDATE_ALL); // future maintainer says: "woot"

是的,这不是一个很好的例子,我知道......

所以,我可以看到这是一件好事,但它提出了你应该多久这样做的问题?如果它适用于每个功能,那么你最终会得到一套不断定义的公制衬衫。

你会在哪里划线?一直坚持魔术数字的常数,或者根据相关函数的使用情况采取混合方式?

5 个答案:

答案 0 :(得分:5)

  

所以,我可以看到这是一件好事,但它提出了你应该多久这样做的问题?如果它适用于每个功能,那么你最终会得到一套不断定义的公制衬衫。

如果每个函数都采用“魔术参数”,那么你已经做错了

总是使用常量。如果你认为这意味着你有太多的常数,那么这只是反映你设计中的其他缺陷。

答案 1 :(得分:3)

正如您已经指出的那样,未来的维护者会感谢您明确命名。这个维护者甚至可能是你,我一次又一次地惊讶于我忘记了自己的代码有多少以及当我一段时间没有处理它时再次理解它有多难。

一旦范围大于可能是一个简短的方法,我肯定会一直使用常量。一旦你开始传递这些值,恕我直言,他们必须被定义为常量。在评论方法可能会做的方法内。但是,这不会帮助您的代码的任何调用者看不到该注释。即使是同一个类中的另一个方法也应该被视为“API客户端”,它不应该知道它在这方面调用的其他方法的实现细节。

使用支持“真实”枚举的语言(如Java 5中引入的Java enum关键字),您甚至可以获得类型安全性,并且不会冒一些基于整数的常量可能具有的唯一性问题的风险。

答案 2 :(得分:2)

我会在它的地方使用它..

  • 提高可读性
  • 帮助你记住
  • 让你看一眼一眼你传递的是什么

以PHP的sort()为例。这是有道理的:

sort($array, SORT_NUMERIC);

但是这会吗?

sort($array, 2); // Haven't actually dug in to see what it matches, but you get the point

答案 3 :(得分:1)

如果你在类中包装东西并使用类常量,那么问题就不那么严重了。除了路径之外,我很少使用全局常量。

答案 4 :(得分:0)

您应该尝试将代码中的文字保持在绝对最小值:每个文字都是潜在的问题,因为您的环境可能会发生变化,并且因为其他开发人员可能不知道它的含义。

当我开始一个项目时,我总是将一个文件专门用于命名常量,通常包含在专门用于此类的类中,并且我自由地使用它们,因为我的工作性质需要它。所有命名的常量都驻留在该文件中,并由该文件控制,为您提供出色的组织和对命名常量的控制。您还可以将它们组织成具有注释或代码区域的组,并根据语言,嵌套并构建一个。

这种做法多年来帮助了我无数次。