2015-03-31 54 views
2

我写了一个使用DI的开源PHP库。可以有依赖注入回退吗?

图书馆有记入的人想使用它的单点,在客户类,它有一个构造看起来像这样(简化):

class Client { 

    protected $depOne; 
    protected $depTwo; 

    public function __construct(DependencyOne $depOne, DependencyTwo, $depTwo) 
    { 
     $this->depOne = $depOne; 
     $this->depTwo = $depTwo; 
    } 
} 

DependencyOne和DependencyTwo也有自己的依赖关系。这意味着,任何人想要使用没有使用DI需要做这样的事情我的图书馆:

$dependencyThree = new DependencyThree(); 
$dependencyFour = new DependencyFour(); 
$dependencyFive = new DependencyFive(); 
$dependencyOne = new DependencyOne($dependencyThree, $dependencyFour); 
$dependencyTwo = new DependencyTwo($dependencyFive); 
$client = new Client($dependencyOne, $dependencyTwo); 
$someStuff = $client->doTheThing(); 

难道是不好使的依赖注入只是该类可选的?例如

class Client { 

    protected $depOne; 
    protected $depTwo; 

    public function __construct(DependencyOne $depOne = null, DependencyTwo, $depTwo = null) 
    { 

     if (!isset($depOne)) { 
      $depThree = new DependencyThree(); 
      $depFour = new DependencyFour(); 
      $depOne = new DependencyOne($depThree, $depFour); 
     } 

     if (!isset($depTwo)) { 
      $depFive = new DependencyFive(); 
      $depTwo = new DependencyTwo($depFive); 
     } 

     $this->depOne = $depOne; 
     $this->depTwo = $depTwo; 
    } 
} 

这意味着有人不使用DI可能只是这样做:

$client = new Client(); 
$someStuff = $client->doTheThing(); 

那些想要使用DI,或用于单元测试目的,依赖仍然可以通过。

这是一个坏主意,如果是这样,为什么?

+0

这并不是一个坏主意,此外,在制作模块/服务/人们使用的任何东西时,建议您在构造函数中构建硬依赖关系。以防万一有人不使用DI – Unex 2015-03-31 08:36:49

回答

1

这正是我在开源项目中所做的,我认为这是一个非常好的解决方案。

它为用户提供了一种方法,让用户不费吹灰之力就可以开始使用您的库,并且同时让他们有可能覆盖任何内容。

另一种解决方案我有时选择是有一个或builder classfactory,参见例如this constructor具有强制性的参数,但ContainerBuilder隐藏这种复杂性。

构建器的优点是它将配置部分带出课程。如果配置部分开始增长(关注点分离),这很有用。

+0

有用,谢谢。我结束了去工厂,所以人们可以通过执行我的库实例化: $ client = ClientFactory :: create($ apiKey); – theandywaite 2015-04-04 09:38:05

1

我同意@Unex。使DI成为可选项并不错,但在构造函数中,我会在库中提供一个工厂。 这样你就可以保持与DI一样的松散耦合,并保持客户端类的单一责任。客户端类为什么知道如何构建其他类?类构造函数是关于自我的知识,仅此而已。请记住,构建一个完整的依赖链可能很大且很复杂,也许你必须在bootstrap中读取配置文件,访问其他php模块中定义的常量,调用实用函数等。你不想在构造函数中拥有所有这些代码。

+0

有用,谢谢! – theandywaite 2015-04-04 09:37:24