【问题标题】:Large number of dependent objects as constructor parameters大量依赖对象作为构造函数参数
【发布时间】:2014-09-23 20:01:37
【问题描述】:

我刚刚了解了依赖注入。但是我遇到了这个问题:因为我的类的一些依赖对象可能非常大的数量,将它们全部传递给类构造函数可能会很长而且不清楚,例如,

interface FooInterface { 
    function fooMethod(); 
} 

class Foo implements FooInterface { 
    function fooMethod(){
        return 'Foo';
    } 
}

class Boo
{
    public $foo;

    public function __construct(FooInterface $foo) // This one is ok because it depends on one object only,
    {
        $this->foo = $foo;
    }
}

class BooFactory
{
    public static function create()
    {
        return new Boo(new Foo);
    }
}

$a = new BooFactory;
$b = $a->create();
var_dump($b->foo->fooMethod());

如果它依赖于很多对象怎么办,

class Boo
{
        public function __construct(FooInterface $foo, TooInterface $boo, PooInterface $poo, etc, etc ,etc, etc, etc) 
        {
        //
         }
}

你不觉得它看起来太多了吗?还是正常?或者我应该怎么做?

【问题讨论】:

  • 这是Dependency Injection Containers(如PimplePHP-DI)设计处理的问题
  • 如果你有这么多的依赖,这会成为一个问题,这是一个强烈的信号,表明你违反了 SRP(单一责任原则),你可能想分成多个类。跨度>
  • @NikiC:我怎样才能把它分成多个类?例如,它是一个控制器类,它需要这些类 - ArticleNavAuth 等,以便根据请求加载页面。

标签: php interface dependency-injection


【解决方案1】:

如果你的类实际上对所有这些对象都有硬依赖(即不是可选依赖),那么这样做是有效的。如果某些依赖项是可选的(例如,也许您可​​以注入一个记录器,但如果它不存在,您就不会执行任何记录),那么请考虑将它们从构造函数中移除并改用 setter 注入。

Setter 注入是您可以照常将$foo 属性添加到您的类的地方,但在构造函数的参数中省略它。然后你会为你的类提供一个setFoo(Foo $foo) 方法,这样你就可以在需要时注入一个Foo 实例。

当一个类有很长的参数列表时,这可能是一种“代码味道”,表明你的类试图做太多事情并且可能没有遵循single responsibility principle。如果您的类试图做太多事情,请考虑将您的代码重构为多个相互消耗的较小类。

【讨论】:

  • 谢谢。 setter injection 是什么?
  • 我已经用关于 setter 注入的简短段落更新了我的答案。
  • 感谢克里斯的编辑。 If your class is trying to do too much, consider refactoring your code into a number of smaller classes that consume each other. 我怎样才能把它分成更小的多个类?例如,它是一个控制器类,它需要这些类 - ArticleNavAuth 等,以便根据请求加载页面。
  • 如果它是一个控制器类,那么它有时会接收很多类作为依赖项是很正常的。如果它失控,请考虑将您的控制器拆分为多个控制器,如果每个控制器的操作完全不同。
  • 顺便说一句,我怎样才能将这些依赖项变成setter注入?请在这里查看我的新帖子stackoverflow.com/questions/25068059/…
猜你喜欢
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
相关资源
最近更新 更多