PHP constructor take in one array instead of multiple params
让所有类构造函数接受一个参数数组,而不是多个参数,这是一个好主意吗?
例如,
1 2 3 4 5 6 7 8 9 10 11 12 13 | class A { private $id; private $name; __construct($arr) { foreach ($arr as $key => $val) { $this->$key = $val; } } } |
而不是
1 2 3 4 5 6 7 8 9 10 11 12 | class B { private $id; private $name; __construct($id, $name) { $this->id = $id; $this->name = $name; } } |
号
这将消除记住参数顺序的需要,并且每次添加新参数时都需要键入"$this->key=$val"。这种方法有什么缺点吗?
虽然这确实是一种观点,但我并不认为这样做是一种很好的做法。您将失去在函数/方法边界强制执行适当的调用签名的能力。您将失去为传递的参数强制类型的能力(或者为支持此功能的IDE提供类型提示)。所以这样的事情不能强制执行:
1 | function foo ($bar, PDO $pdo_obj) {} |
号
您还将失去提供以下默认参数值的能力:
1 | function foo ($bar, $optional = 'default') {} |
您还可能使该方法暴露于意外行为。例如,如果其中一个采用您在示例中建议的方法。如何防止调用者传递可能耗尽内存分配的任意长度的数组?
实际上,你甚至不应该设计一个可以接受超过3或4个参数的函数,所以我不知道你在这里真正得到的是什么,除了能够以未定义的顺序得到"参数"。这种"灵活性"的代价是,然后需要围绕任何参数创建数组包装器,否则将直接传递给函数/方法。
最后,我要说明的是,您建议的方法并不是PHP中的典型编码实践。因此,如果您曾经期望其他人使用您的代码,那么这种方法可能会让他们感到困惑,因为它不是通常会遇到的事情。
缺点是你根本没有暗示的类型。如果您有单独的参数,并且使用了适当的IDE(如netbeans或phpsorm),那么您将有可用的工具来帮助您记住参数的顺序。如果您只是传入一个数组,那么您就没有这些信息,没有类型提示,也没有具体的错误,以防忘记添加参数或稍后添加参数,而忘记更改对构造函数的某个调用。
所以我选择不这样做,尽管在这个问题上意见可能有所不同。在JavaScript中,这似乎更常见。jquery和其他库很大程度上依赖于这种机制,但是对于PHP,我不会,因为上面描述的原因。
缺点是您更可能忘记设置特定的参数。不过,有很多方法可以控制这种情况。我所知道的最好的方法是创建一个异常类,如
我会加一张这样的支票:
1 2 3 | if(property_exists($this, $key)) { $this->$key = $val; } |
为了防止随机未知属性的意外设置。
我担心的是,您的对象在构造函数中需要如此多的参数,以至于您无法保持它们的直线性。请查看有多少构造函数参数太多,无法讨论不同的设计模式。
我认为这是不好的。
客观地说,我认为这会使任何维护您的代码库的人更难遵循代码,因为它是非常规的。此外,我认为当您消除了记住参数顺序的需要时,您更可能引入错误,因为您在代码中添加了一层模糊。
诚然,我认为这是一个糟糕的部分原因是因为我第一次学习Java编程,对Java设计模式有偏见,认为一致性很重要。