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


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

有时候,问问题的最好方法,就是我自己尝试解决它......

假设我有一个班级:

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;
    }
}

是的,这在两个类之间创建了耦合,但这并不总是错误的。