有时候,问问题的最好方法,就是我自己尝试解决它......
假设我有一个班级:
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;
}
}
是的,这在两个类之间创建了耦合,但这并不总是错误的。