如何解决PHP中的钻石问题



我已经寻找了钻石问题的解决方案,但我发现的唯一一个是使用我不能在我的情况下使用的特征,所以我在这里问一下是否有人有替代解决方案。

我有一个基类Controller(我不能改变这个类),有两个子类SecurityControllerDevController。这些子类中的每一个都引入了一些方法,这些方法也使用基类中的方法。然后我有一个最后的类ApplicationController,理想情况下,将扩展SecurityControllerDevController。当然,这在PHP中是不可能的(仅限单继承)。

所以我的问题是——解决这个问题的最好方法是什么?我遇到了特征,但后来意识到这不起作用,因为2个子类(我认为可能适合特征)都需要扩展Controller来访问它里面的方法。我能看到的唯一其他替代方案是强迫SecurityController扩展DevController(反之亦然)。虽然这样做是不理想的,因为这两个类来自不同的模块,我希望创建作为一个drop in和使用作为类型的插件。

这篇关于代码审查的文章看起来很有希望。另一种选择是好的——我觉得当我试图改进代码时,我很可能会引入错误。

解决方案说明

一般来说,公认的答案仍然是我找到的解决这个问题的最好方法。然而,在这种情况下,我可以使用特征。我在SecurityController中有一个名为beforeExecute($dispatcher)的方法-通过将其更改为beforeExecuteTrait($controller, $dispatcher)并使SecurityController成为一个特征,然后让ApplicationController扩展Controller,使用SecurityController并在ApplicationController中添加方法

public function beforeExecute($dispatcher)
{
    return $this->beforeExecuteTrait($this, $dispatcher);
}

并通过将相同的逻辑应用于DevController,我实现了所需的行为。

听起来您可以从依赖注入中获益。换句话说,您将实例化其他类,然后将这些实例注入到您的主类中以供使用。这避免了PHP中继承的混乱。

class A extends B {
}
class C {
    /** @var A */
    protected $classa;
    public function __construct(A $class) {
         $this->classa = $class;
    }
}
$a = new A();
$c = new C($a);

最新更新