假设我有这样的课程:
class Foo{
public function bar($p,$p2=null,$p3=null){
//...
}
}
有时我需要调用它只传递第一个和第三个参数。问题是我必须放第二个参数,传递任何东西,才能达到第三个。
我可以为可选参数创建私有属性和设置方法,并将它们从方法签名中删除。
这是一个好习惯吗?或者它更好地使用__call
或func_get_args
代替?
我在 SO 中读过的资料:
并在手册中:
假设我有这样的课程:
class Foo{
public function bar($p,$p2=null,$p3=null){
//...
}
}
有时我需要调用它只传递第一个和第三个参数。问题是我必须放第二个参数,传递任何东西,才能达到第三个。
我可以为可选参数创建私有属性和设置方法,并将它们从方法签名中删除。
这是一个好习惯吗?或者它更好地使用__call
或func_get_args
代替?
我在 SO 中读过的资料:
并在手册中:
我可以为可选参数创建私有属性和设置方法,并将它们从方法签名中删除。
如果原因是您希望他们让开,那么这样做将是一个非常糟糕的主意。
什么是参数和什么是属性是构成类设计的决策,因此只有在查看大图(与任何其他设计决策一样)之后才能将一个交换为另一个。不要进行这种更改,因为您不喜欢一个特定方法的特定调用站点的读取方式。
我们无法判断将参数改为属性是否有意义,因此对于其余部分,我将假设它没有意义。在这种情况下有哪些选择?
如果这些问题的答案是“是”,则可能表明该方法根据参数以不同的模式运行。在这种情况下,将模态行为分解为具有简化签名的单独方法是有意义的。
如果这些问题的答案是“是”,那么您可以使该方法接受一个数组作为其最后一个参数,并将其用作“其他选项”的容器。
这种方法有一个(大!)缺点,这些选项不再通过方法签名进行宣传,但如果有合理的默认值,你不会在 90% 的时间里触及它,它就有意义了。
如果有很多可以指定的选项,那么创建一个流畅的接口是有意义的,但这是一个很大的改变,除非有额外的参数(例如,如果需要可组合性),否则不应该做出改变。您可以将流畅的界面视为将参数转换为属性的更好设计版本。
编写流畅的接口涉及一个新类,该类封装了所有可能进入函数调用的参数;该类对每个参数都有一个方法,以及一个或多个使用这些参数工作的方法。一个流畅的接口调用站点看起来像
$foo->bar()->color('red')->type('widget')->execute();
这里$foo->bar()
返回封装类的实例,color
并且type
是该类上设置属性并execute
读取这些属性并执行实际工作的方法。
你怎么能用 or 定义哪个参数是第二个或第三funct_get_args
个call
?只有当它们有不同的类型时才有可能。
在我看来,如果您想要一种强大的方法来处理许多可能是可选参数的参数,请使用像捆绑对象(通用或特定于您的函数)这样的容器,或者更友好的是关联数组。