【问题标题】:Avoiding inheritance, how could I give my class a default creation dependency?避免继承,我怎么能给我的类一个默认的创建依赖?
【发布时间】: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 之后的属性和方法。字符只是一个变量名。
  • 是的,理想情况下,我想将 __constructorsetTeacher 方法放在 **Trait** 中(以获得更多的灵活性!和 DRY),然后将其放入每个班级需要这个设置。我避免使用此解决方案进行继承,但我仍然可以利用继承带来的默认设置的优势。我不喜欢在每次使用课程时都不必要地冗长并删除一个教师实例,因为现在可能有 99% 的时间教师将是绝地。
  • 实际上@ItayMoav-Malimovka 稍后我可能想添加一个名为character 的基类的想法实际上是我的问题提出的另一个好点。关于灵活性,保持该选项打开会很好(因为 PHP 是单继承),所以更需要做一些我在问题中提出的事情。
  • 一旦引入特征,PHP 就不再是单继承语言。

标签: php design-patterns dependency-injection php-5.5


【解决方案1】:

你可以接受null作为参数,如果为null则创建依赖:

class AnakinSkywalker implements Apprenticeable {

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

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

【讨论】:

    猜你喜欢
    • 2018-10-22
    • 2018-06-07
    • 2015-02-27
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    相关资源
    最近更新 更多