【发布时间】:2015-03-13 02:40:56
【问题描述】:
有时最好的提问方式是我自己尝试解决它...
假设我有一堂课:
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"
...
这是一个适当的、可测试的、松散耦合的解决方案,可以为对象提供默认依赖项,并能够在以后更改它吗?如果不是,为什么,我该怎么做才能做到这一点?
【问题讨论】:
-
阿纳金不应该是一个对象,而角色应该是一个类吗?此外,做你觉得对的事。编程不是一门精确的科学
-
哦,我的示例选择在那里并不完美,抱歉!但实际上 Anakin 是 Apprenticeable 的一个独特实现的名称。当然,也许我以后可以从 Character 基类扩展 Anakin。但对于这个例子,这不是我要问的。我正在创建许多这些类来保存 Apprenticeable 之后的属性和方法。字符只是一个变量名。
-
是的,理想情况下,我想将
__constructor和setTeacher方法放在 **Trait** 中(以获得更多的灵活性!和 DRY),然后将其放入每个班级需要这个设置。我避免使用此解决方案进行继承,但我仍然可以利用继承带来的默认设置的优势。我不喜欢在每次使用课程时都不必要地冗长并删除一个教师实例,因为现在可能有 99% 的时间教师将是绝地。 -
实际上@ItayMoav-Malimovka 稍后我可能想添加一个名为
character的基类的想法实际上是我的问题提出的另一个好点。关于灵活性,保持该选项打开会很好(因为 PHP 是单继承),所以更需要做一些我在问题中提出的事情。 -
一旦引入特征,PHP 就不再是单继承语言。
标签: php design-patterns dependency-injection php-5.5