在 Laravel 中, Eloquent \Builder类将每次调用发送到它不需要内部Query\Builder 的方法。对我来说,这听起来像是继承。有人知道为什么他们没有实现它以便Eloquent\Builder扩展Query\Builder?我第一次注意到它的原因是我在 IDE 中遇到了“调用未定义方法”错误,尽管代码工作正常,这是我认为的魔法方法的诅咒。
作为参考,这里是来自Eloquent\Builder.
/**
* The base query builder instance.
*
* @var \Illuminate\Database\Query\Builder
*/
protected $query;
protected $passthru = array(
'toSql', 'lists', 'insert', 'insertGetId', 'pluck', 'count',
'min', 'max', 'avg', 'sum', 'exists', 'getBindings',
);
public function __call($method, $parameters)
{
if (method_exists($this->model, $scope = 'scope'.ucfirst($method)))
{
return $this->callScope($scope, $parameters);
}
else
{
$result = call_user_func_array(array($this->query, $method), $parameters);
}
return in_array($method, $this->passthru) ? $result : $this;
}
Run Code Online (Sandbox Code Playgroud)
我将从我的结论开始。我认为它只是设计得很糟糕。
让我做一些解释,并回复 @Simon Bengtsson 接受的答案
我无意冒犯任何人,只是想表达我的想法。
实际上,继承的全部意义在于它们具有相似的特性,但您想添加一个额外的层来放置一些扩展功能。显然,扩展的“子”类会比“父”类知道更多(比如了解 Eloquent Model)
对我来说,“建设者”就是建设者。毕竟,两者实际上都在构建查询,无论其检查或观察什么条件。这就是构建器的目的(至少从我看来)。所以它位于同一层(除了Eloquent\Builder有一些额外的功能)。
当前的实现覆盖了一些方法的性质,例如 where() (基本上是 中的方法Query\Builder,相同的名称,相同的参数)。它还添加了一些方法,最终调用像 where() 这样的方法。这都是关于继承的。如果我调用 where(),并且它存在于子类中,则会调用子类方法。如果没有,就会调用父类的方法。
如果您假设想要使用一些新的 NoSQL DB 并简单地编写一个符合 Query\Builder 签名的插入类,那么以后,解耦低级和 ORM 级组件就会变得更加困难。
@西蒙·本特森
我不明白脱钩是如何变得困难的。您所要做的就是编写一个新类Query\MongoDBBuilder,它与Query\Builder. 如果您担心,您始终可以使类“实现”接口。如果你问我,实际上目前的方式更难解耦,因为现在“哪些功能被覆盖,哪些没有”非常混乱。
在某些情况下,我确实鼓励类解耦,但如果我要解耦这个类(我认为这里没有必要),我会这样做:
Eloquent\ModelEloquent\Adapter(这是某种中间层,您可以在其中放置连接设置等)Eloquent\Builder extends Query\Builder(这是 Query\Builder 的“包装器”,因此它可以做更多的事情,但实现相同的目标)子类还可以访问父类上受保护的属性,以便 Eloquent\ChildOfQueryBuilder 可以自由地依赖 Query\Builder 的低级实现,并可以与其耦合。
@西蒙·本特森
这就是继承的全部要点。您将能够访问受保护的属性来覆盖父级提供的功能。让我们从另一个角度来看,如果您需要访问这些变量来修改功能怎么办?事实上,作者声明这些成员“受保护”已经暗示他已经准备好另一个类来扩展它。这是使其“受到保护”的唯一目的,对吗?
这就是为什么在继承父类之前您必须确切地知道它在做什么,因为这可能很危险。
我之所以给出这么长的解释是因为我正在尝试修改 Eloquent 的一些功能。我一直在研究days的实现(3个神类:Eloquent\Model、Eloquent\Builder和Query\Builder)。分层和锯齿真的很混乱。Model由于其实现不佳,扩展该类需要我重新声明几乎等效的函数。但这不是主题。
总之,如果你问“为什么”,我实际上会说(现在我知道人们会踢我)它只是设计和实施不佳。
| 归档时间: |
|
| 查看次数: |
2223 次 |
| 最近记录: |