Function 良好的编码实践:何时创建新函数

Function 良好的编码实践:何时创建新函数,function,language-agnostic,code-readability,Function,Language Agnostic,Code Readability,我有一个特定的函数,它使用相同的代码行4次(很少,2-5次,取决于我如何更改它以适应将来可能的使用) 我看了一下,但对我来说不够具体,也不符合我要去的方向 这里有一些伪的: function myFunction() { if (something) { // Code line 1 // Code line 2 // Code line 3 } else if (somethingElse) { // Code line 1 // Code

我有一个特定的函数,它使用相同的代码行4次(很少,2-5次,取决于我如何更改它以适应将来可能的使用)

我看了一下,但对我来说不够具体,也不符合我要去的方向

这里有一些伪的:

function myFunction() {
  if (something) {
    // Code line 1
    // Code line 2
    // Code line 3
  }
  else if (somethingElse) {
    // Code line 1
    // Code line 2
    // Code line 3
  }
  else if (anotherThing) {
    // Code line 1
    // Code line 2
    // Code line 3
  }
  else if (theLastThing) {
    // Code line 1
    // Code line 2
    // Code line 3
  }
  else {
  // Not previously used code
  }
}
复制/粘贴相同的3行代码(如果满足其中任何一个条件,则构造相同的对象)。创建一个函数,我可以将所有这些信息传递给它,并在完成时返回必要的信息,这是一个好的做法吗?所有这些条件语句都在一个循环中,该循环最多可以运行1000次左右

我不确定通过跳转到另一个函数来准备堆栈帧(?)的成本是否比1000次迭代的成本更高,是否值得拥有约15行重复代码。显然,将其函数化会使其更具可读性,但是这是一个非常特殊的功能,在其他任何地方都没有使用。我可以编写的消除复制/粘贴心态的函数如下:

function myHelperFunction(someParameter, someOtherParameter) {
  // Code line 1
  // Code line 2
  // Code line 3
  return usefulInformation;
}
然后在所有这些条件语句中调用函数,每个条件语句调用一行:

myHelperFunction(myPassedParameter, myOtherPassedParameter);
基本上把这12行变成了4行

所以问题是-一般来说,这是一个好的实践吗?,用非常少量的代码创建一个新函数,以节省一些空间和可读性?或者,跳转函数的成本太高,不值得吗?一个人是否应该总是为将来可能复制/粘贴的任何代码创建一个新函数

PS-我知道,如果这段代码用于不同的(类)或源文件,那么将其转换为一个函数是合乎逻辑的,以避免为了进行更改而需要找到复制/粘贴它的所有位置。但我说的或多或少是单个文件/单个类或函数,这有点进退两难。
另外,如果我做得不正确,请随时修复我的标签/标题。我真的不知道如何正确地给这篇文章加上标题/标签。

这是一个很好的问题,答案是:这取决于具体情况


就我个人而言,我会创建一个函数来提高代码的可读性,但如果你想提高效率,也许你会希望保留复制和粘贴的代码。

是的,创建一个函数,通常你应该遵循DRY原则。不要重复你自己

对于这样的事情,堆栈操作将是最小的。请参阅Imre Kerr对您的问题的评论


这不仅仅是为了可读性。这么多原因。可维护性是巨大的。如果必须更改此代码,那么其他人会很痛苦,他们会尝试找出每个地方进行更改。只需在一个地方更改代码要好得多。

在我看来,您的做法是错误的。首先,您不应该使用多个执行相同代码的(else)if;使用一个复合或预计算(在这种情况下,由于所有可能的子条件,我建议预计算)条件。这样做可能会使维护代码变得更容易

function myFunction() {
  bool condition = something ||
                   somethingElse ||
                   anotherThing ||
                   theLastThing;

  if (condition) {
    // Code line 1
    // Code line 2
    // Code line 3
  }
  else {
  // Not previously used code
  }
}

对于任何不属于算法/数据结构问题的优化问题,答案都是:评测代码!只优化显示为问题区域的内容


这意味着您应该找出函数调用开销是否实际上是您正在编写的特定程序中的性能问题。如果是,则内联代码。如果不是,就不要。就这么简单。

我不知道这是否适用于您提供的示例,但分解代码并不是编写函数的唯一原因,您还可以从测试的角度来考虑

函数提供可单独测试的编程单元

因此,您可能会将一个复杂的操作分解为几个更简单/更基本的单元,即使这些函数只调用一次

既然你问了几行代码的问题,你可以问自己:

  • 我能合理地命名这个函数吗?
    (只需这样做就可以了,是这样还是那样,还有其他不那么好的事情)
  • 它有合理数量的参数吗?
    (我会说两个或三个)
  • 是否值得将其作为一个单独的单元进行测试?
    (它是否简化了总体测试)
  • 通过这样的函数调用,代码是否更可读/更易懂?
    (如果前两个问题的答案为否,则不一定很明显)

如果可能,许多编译器/解释器可以/将使用内联函数,这意味着除非您的函数是递归的(有时甚至是递归的,请参见),否则您可以无需任何开销地调用它。我只是读了一点内联函数——这是C/C++/C特定的吗?或者Javascript编译器也会这样做吗?我没有指定任何我希望函数内联的标志,我也不确定JS编译器是否会自动知道何时使函数内联。你有什么想法吗?我不确定谷歌的JS服务,但IonMonkey(Firefox使用的编译器)有函数内联。因此,在JS中完全可以这样做。至于要内联哪些函数,打开内联的编译器将内联他们认为“简单”到值得内联的每个函数。好吧,我很了解谷歌,我相信他们的JS服务确实做到了这一点!就性能而言,我只能说这要视情况而定。许多环境(例如(.net和JVM)可能会为您内联这一功能。为了可读性,我会这样做,然后检查它是否会对性能产生负面影响,但这不太可能。这些条件包含多个比较器,即如果(x>y&&y。乘以4,你有12个条件。如果对所有这4个条件进行2+比较,那么为所有这4个条件声明一个布尔值仍然有效吗?PS-这是Javascript,我不确定这是否是该语言的语法限制,但请告诉我,因为这将是实际的