避免继承,我怎么能给我的 class 一个默认的创建依赖?

Avoiding inheritance, how could I give my class a default creation dependency?

有时提出问题的最佳方式是我自己尝试解决问题...

说我有一个 class:

use App/Jedi;
use App/Interfaces/Teacher;   // <-- Jedi is an implementation of Teacher

class AnakinSkywalker implements Apprenticeable;
{
    private $teacher;
    public $lightSaberColor = "blue";

    public function __construct(Jedi $teacher){  // <-- default Teacher
        $this->setTeacher($teacher);         
    }        

    public function setTeacher(Teacher $teacher){  // <-- can change later here
         $this->teacher = $teacher; 
    }

    public function printHowManyCanTeach(){
        echo $teacher->count();
    }

    // ...
}

我的应用程序中有很多地方我是这样使用的:

$character = new AnakinSkywalker;
echo $character->howManyCanTeach();    // prints "Many masters"
...

但有一天我决定在我的应用程序中的某个特定位置改为执行此操作:

$sith = new Sith;   // <-- Sith is an implementation of Teacher
$characher = (new AnakinSkywalker)->setTeacher($sith);
echo $character->howManyCanTeach();  // prints "Always two there are, no more, no less"
...

这是一个适当的、可测试的、松散耦合的解决方案,可以为对象提供默认依赖项,并能够在以后更改它吗?如果没有,为什么,我该怎么做才能做到这一点?

您可以通过接受 null 作为参数来实现,如果它是 null,则创建依赖关系:

class AnakinSkywalker implements Apprenticeable {

    public function __construct(Teacher $teacher = null) {
        if ($teacher == null) {
            $teacher = new Jedi();
        }
        $this->teacher = $teacher;
    }
}

是的,这会在两者之间产生耦合 类,但这并不总是错误的。