有很多参数的函数是不好的形式吗?有啥选择?
Posted
技术标签:
【中文标题】有很多参数的函数是不好的形式吗?有啥选择?【英文标题】:Is it bad form to have functions with a lot of parameters? What's the alternative?有很多参数的函数是不好的形式吗?有什么选择? 【发布时间】:2011-02-08 13:17:55 【问题描述】:我有一个查询数据库的搜索功能,并且有大约 15 个可选参数。显然这并不漂亮,称它为有点乱。 php 不允许重载方法,所以我一直在创建巨大的函数签名。
我在其他地方看到了诸如创建参数类之类的建议:Disadvantages of using a lot of parameters
但这似乎太重了。我可以传入一个关联数组,但是虽然这减少了参数的数量,但我认为这不太容易理解,因为没有内置文档说明数组中应该存在哪些键。
还有其他方法可以优雅地处理这个问题吗?通常在其他语言中,我会有一个非常丑陋的 private
方法,它最多需要十几个参数,然后创建同名的 public
方法,这些方法接受这些参数的子集并在内部调用私有方法。
【问题讨论】:
【参考方案1】:在PHP中,可以使用关联数组:
someFunction(array(
"a" => 3243,
"b" => 2354,
"c" => 33453,
"d" => 324353,
"e" => 321243,
"f" => 321243,
"g" => 312243,
"h" => 321243,
))
或正在调用该函数的对象的属性(如果有意义的话)。 PHPMailer 发送这样的邮件:
// instantiate the class
$mailer = new PHPMailer();
// Set the subject
$mailer->Subject = 'This is a test';
// Body
$mailer->Body = 'This is a test of my mail system!';
// Add an address to send to.
$mailer->AddAddress('foo@host.com', 'Eric Rosebrock');
if(!$mailer->Send())
echo 'There was a problem sending this mail!';
它还有更多的可选参数。它也可以使用具有数百个参数的方法,但这更具可读性。
编辑:这些解决方案还更好地支持可选参数。在属性的情况下很简单,在关联数组的情况下,您可以将数组与默认值数组合并。
【讨论】:
使用数组作为参数还有一个好处是不会强迫你创建参数的层次结构。在你的函数开始时,你仍然可以检查是否给出了所需的参数。 是的,但是函数签名中没有有意义的文档——除非我单独记录并保持最新,否则有人怎么知道允许哪些参数? 执行此操作的好地方是 Doxygen/PHPDoc 评论(如果您不了解这些,请在 Google 上搜索)。然后,高级 IDE 将能够在输入代码时向您显示此类文档。【参考方案2】:通常,长参数列表是代码中所谓的不良气味,可以通过称为 Introduce 参数对象的重构来删除。参考this。
干杯
【讨论】:
【参考方案3】:是的,好的经验法则是不超过 3-4 个参数。如果您需要更多,那么通常您应该使用数组或对象作为参数之一。但在某些情况下,如果你认为你真的需要更多参数,那么当然,为什么不呢。如果它使您的代码易于理解和使用,那为什么不呢。
【讨论】:
【参考方案4】:您可以创建一个将参数存储为属性的类,允许您根据需要设置每个属性,然后有一个使用这些属性来查询数据库的方法。构造函数可以为这些属性设置默认值。这只是让调用更容易一些。
$function = ClassFunction();
$function->arg1 = 'Some value.';
$function->arg2 = true;
$function->arg3 = 5;
$result = $function->call_method(); // This uses default values for any property not set.
【讨论】:
【参考方案5】:在我看来,“参数过多”的问题只是一个更深层次的问题的表现:糟糕的架构。如果一个函数真的需要所有这些参数值,那么很有可能它做得比它应该做的要多得多。
这应该是一个提醒“哦,嘿,让我们重新考虑不要使用过程 X 来做所有的事情,而是想想 X 应该真正做什么以及 Y 和 Z 应该做什么。
【讨论】:
【参考方案6】:将您的函数转换为类会很好。有两个主要优点:
函数参数转换为属性并可以注释
我认为比较大的函数代码可以拆分成一组更小的私有方法
【讨论】:
以上是关于有很多参数的函数是不好的形式吗?有啥选择?的主要内容,如果未能解决你的问题,请参考以下文章
Paypal 中定期付款的 IPN 与普通发票付款有啥不同的参数吗?