代码之家  ›  专栏  ›  技术社区  ›  Drew

什么时候改变一个函数,什么时候写一个新函数…?

  •  2
  • Drew  · 技术社区  · 16 年前

    N900B

    通过在这里编码的知识和专业知识的天赋,我在学习编程的基础知识时尽最大努力避免n00b错误。

    当我(认为我)可以在php中使用函数时,我会使用函数,并在不同的include中对它们进行排序。

    我现在遇到的n00b问题是,现有函数的4/5可能与新需求相关。可能有一组稍有不同的输入,或者序列中有一两个额外的计算,或者输出需要不同的格式/结构…但该功能的核心仍然适用。

    有没有一个很好的经验法则来说明什么时候应该把垃圾添加到原始函数中,什么时候应该(字面上)将大部分内容复制粘贴到新函数中并进行调整以适应这种情况?

    一方面,我觉得很糟糕的代码重复,另一方面,我觉得很糟糕的杂乱与不总是需要的东西现有的功能…

    5 回复  |  直到 16 年前
        1
  •  5
  •   Thomas    16 年前

    一个好的经验法则是:不要复制粘贴。

    如果功能A和B的四分之五相同,则将它们分开。让它们都调用一个实现公共部分的新函数c。

    如果你告诉代码你在哪里有这个问题,我们可以建议如何最好地分割它。

        2
  •  0
  •   MadMurf    16 年前

    我同意@thomas的前提条件,在将公共位分割成一个新函数之前,您的新函数和修改过的旧函数需要进行一些影响分析。

    您的项目经理、测试团队和客户不会感谢您,如果您的漂亮代码的目标是以对以前超出范围的应用程序区域进行显著的回归测试为代价的话。

    在这些情况下,如果没有时间/金钱来做“正确”的事情,我将不情愿地复制粘贴或编写一个新的函数,它使用旧的函数来弥补额外的1/5所需,并用一个注释将其包围

    >>>>>HACKCIDENT ZONE, 
    >>>>>NEXT TIME THIS CODE IS CHANGED THE OPPORTUNITY SHOULD BE TAKEN TO CORRECT THIS HORROR
    .....
    .....
    <<<<END OF HACKCIDENT ZONE - move on nothing more to see here
    

    这不太理想,但它让我对自己感觉好一点…

        3
  •  0
  •   Johannes Rudolph    16 年前

    为什么你发现你的职能部门在做4/5相同的工作?显然,你没有很好的抽象和责任分离。

    一个函数应该总是做一件事,把它做好。让我们以一个平均值函数为例,该函数从整数数组计算平均值。一个简单的实现将把所有元素相加,然后除以元素的数量。但是这个除法有个问题,它知道如何求整数数组的和。这违反了上述约束。更好的实现是将sum()函数与average()分开,并让average()使用sum()来获取整数数组的和。“一个函数应该只做一件事”这句话的谐音是“一个函数应该只知道如何做一件事。对于其他一切,它可能依赖于其他抽象(例如函数)。”

    从清晰的抽象和责任分离中你能得到什么?

    • 代码的可组合性更好,编写新函数更容易
    • 无复制粘贴编码,将潜在的错误代码散布到整个代码库中
    • 更好的可读性,读者不会被与函数应该做什么没有直接关系的事情的实现细节分散注意力
    • 允许透明的性能优化
        4
  •  0
  •   Pier-Luc Gendreau    16 年前

    想干或死-不要重复你自己和重复是邪恶的!

    把你的职能分开。如果您将一个函数的4/5复制到5个不同的文件中的5个不同的函数中,并且发现其中一个文件中有一个bug,那么您可能会忘记至少更新其中一个。

        5
  •  0
  •   Josiah    16 年前

    这不是一个关于函数中的代码是相同的问题,而是关于函数的目的是什么,以及它是否与要创建的函数的目的匹配的问题。

    考虑一下如果你有一个计算小部件的函数:

    function count_widgets($widgets)
    {
        // Counting functionality
    }
    

    你需要一个新的函数来计算它的数量,但是要共享它的功能。您可以创建一个计算窗口小部件或内容的函数:

    function count_widgets_or_whatsits($thing)
    {
       if( $thing instanceof Whatsit )
       {
         // Special whatsit stuff
       }
       // Counting functionality
    }
    

    但那会打破 合同 函数的。相反,您应该创建一个新函数,并提取公共功能:

    function count_widgets($widgets)
    {
        return count_things($widgets);
    }
    
    function count whatsits($whatsits)
    {
        // Special whatsit stuff
        return count_things($widgets);
    }
    
    function count_things($things)
    {
       // Counting functionality
    }
    

    这将:

    1. 使您的代码对其他人更具可读性。(有人很容易猜到 count_whatsits() 会数瓦茨)
    2. 提供了一个 合同 在所谓的和正在发生的之间。如果计数过程发生了变化,您可以简单地修改 数一数 不影响小部件计数的功能。
    3. 当你改变了一些影响到其他事情的东西时,你就省去了几个小时的维护问题。
    推荐文章