2

假设我有这样的课程:

class Foo{
    public function bar($p,$p2=null,$p3=null){
        //...
    }
}

有时我需要调用它只传递第一个和第三个参数。问题是我必须放第二个参数,传递任何东西,才能达到第三个。

我可以为可选参数创建私有属性和设置方法,并将它们从方法签名中删除。

这是一个好习惯吗?或者它更好地使用__callfunc_get_args代替?

我在 SO 中读过的资料:

并在手册中:

4

2 回答 2

2

我可以为可选参数创建私有属性和设置方法,并将它们从方法签名中删除。

如果原因是您希望他们让开,那么这样做将是一个非常糟糕的主意。

什么是参数和什么是属性是构成类设计的决策,因此只有在查看大图(与任何其他设计决策一样)之后才能将一个交换为另一个。不要进行这种更改,因为您不喜欢一个特定方法的特定调用站点的读取方式。

我们无法判断将参数改为属性是否有意义,因此对于其余部分,我将假设它没有意义。在这种情况下有哪些选择?

选项 #1:重构

  • 在这个方法上有两个可选参数有意义吗?
  • 在调用它时,您通常会忽略其中一个(或两个)吗?

如果这些问题的答案是“是”,则可能表明该方法根据参数以不同的模式运行。在这种情况下,将模态行为分解为具有简化签名的单独方法是有意义的。

选项 #2:属性捆绑

  • 这种方法是否有很多具有合理默认值的参数?
  • 在典型的通话中,您通常只提供其中的几个(或不提供)吗?

如果这些问题的答案是“是”,那么您可以使该方法接受一个数组作为其最后一个参数,并将其用作“其他选项”的容器。

这种方法有一个(大!)缺点,这些选项不再通过方法签名进行宣传,但如果有合理的默认值,你不会在 90% 的时间里触及它,它就有意义了。

选项#3:流畅的界面

如果有很多可以指定的选项,那么创建一个流畅的接口是有意义的,但这是一个很大的改变,除非有额外的参数(例如,如果需要可组合性),否则不应该做出改变。您可以将流畅的界面视为将参数转换为属性的更好设计版本。

编写流畅的接口涉及一个新类,该类封装了所有可能进入函数调用的参数;该类对每个参数都有一个方法,以及一个或多个使用这些参数工作的方法。一个流畅的接口调用站点看起来像

$foo->bar()->color('red')->type('widget')->execute();

这里$foo->bar()返回封装类的实例,color并且type是该类上设置属性并execute读取这些属性并执行实际工作的方法。

于 2013-10-01T10:19:29.217 回答
1

你怎么能用 or 定义哪个参数是第二个或第三funct_get_argscall?只有当它们有不同的类型时才有可能。

在我看来,如果您想要一种强大的方法来处理许多可能是可选参数的参数,请使用像捆绑对象(通用或特定于您的函数)这样的容器,或者更友好的是关联数组。

于 2013-10-01T10:01:32.173 回答