PHP OOP:每个参数类型的唯一方法?
Posted
技术标签:
【中文标题】PHP OOP:每个参数类型的唯一方法?【英文标题】:PHP OOP: Unique method per argument type? 【发布时间】:2010-05-07 14:40:04 【问题描述】:我正在编写一些自制的 ORM(学术兴趣)。我正在尝试将 TDD 概念作为一项培训练习,并且作为该练习的一部分,我在开发课程时正在为 API 编写文档。
举个例子——我正在研究一个经典的“getCollection”类型映射器类。我希望它能够为特定用户检索资产 X 的集合(比如说博客文章),以及基于任意数值数组的集合。所以 - 你可能有一个像这些中的任何一个的方法
$User = $UserMapper->load(1);
$ArticleCollection = $ArticleMapper->getCollection(range(10,20));
$ArticleCollection = $ArticleMapper->getCollection($User);
$ArticleCollection = $ArticleMapper->getCollection($User->getId());
因此,在编写 getCollection 方法的文档时 - 我想在 Docblock 中声明 @param 变量。是为每种参数类型设置一个唯一的方法更好,还是根据参数类型委托给正确的内部方法/类的方法是否可以接受?
【问题讨论】:
【参考方案1】:拥有一个委托给正确内部方法的方法是可以接受的。你可以像这样记录它:
@param Array|User|Integer $argName optional explanation
但话又说回来,没有人会阻止你每个人都有一种方法
public function getCollectionByRange(array $range)
public function getCollectionByUser(User $user)
public function getCollectionByUserId($id)
此外,您可以使用magic __call
method 假装上述方法存在,然后捕获对它们的方法调用并委托给您的内部方法(ZF does that f.i. for finding dependant database rows)。您将在 Class DocBlock 中使用 @method
注释记录这些方法。但请记住,魔术方法总是比直接拥有和/或调用适当的方法慢。
使用您认为对您的应用程序和用例最有意义的内容。
【讨论】:
【参考方案2】:您可以通过在运行时检查传递参数的类型来实现类似method overloading 的功能(php 不支持从其他语言(例如 ADA、Java、C# 或 C++ 等)已知的这一概念):
[...]
/**
* @param User|array|integer $user
* @return array
*/
public function getCollection($user)
// perhaps a switch-case would be better here
if ($user instanceof User)
// do what has to be done if you passed in a User object
else if (is_int($user)
// do what has to be done if you passed in a user id
else if (is_array($user))
// do what has to be done if you passed in an array of user ids
[...]
【讨论】:
感谢您的回答 - 但是,我对如何做,而不是为什么(或什么被认为是“最佳实践”)不太感兴趣 “使用你认为对你的应用程序和用例最有意义的东西。” - 我想 Gordon 是在 26 分钟前添加的。在大多数情况下,我认为没有最佳方法:这取决于。我个人会选择一种方法,因为它使 API 保持整洁。【参考方案3】:它听起来就像你想做函数重载,但是 PHP(甚至 PHP5)不像你在 Java 中那样做重载。 PHP手册中的Overloading section不是function overloading:
注意:PHP的解释 “重载”与大多数不同 面向对象的语言。重载 传统上提供的能力 有多个相同的方法 名称,但不同的数量和 参数类型。
你可能是这个意思:
class ArticleMapper
public function getCollection($param)
if (is_array($param)) $this->getCollectionByArray($param);
if (is_int($param)) $this->getCollectionByInt($param);
if (is_a($param, 'User')) $this->getCollectionByUser($param);
private function getCollectionByArray(array $param) ...
private function getCollectionByInt($param) ...
private function getCollectionByUser(User $param) ...
在我看来,这似乎是个不错的方法。
【讨论】:
谢谢,感谢您的回答,并且非常接近我的初始实施。我很想知道的是,从 OOP 最佳实践的角度来看,使用独特的方法 re: 责任是否更好? 啊,好点子:php.net/manual/en/language.oop5.typehinting.php 我会从我的回答中删除那个错误的int
。以上是关于PHP OOP:每个参数类型的唯一方法?的主要内容,如果未能解决你的问题,请参考以下文章