2008-12-18 136 views
3

我正在编写一个考虑可测试性的PHP应用程序,所以我的类总是在它们的构造函数中询问它们依赖的“协作对象”,就依赖注入模式而言。给PHP对象类型参数一个默认值

这样,我就可以在我的单元测试中通过模拟或测试实现。

我想实现的目的是为了能够实例化一个具有传递给它的构造函数参数的空值的类,以便触发一个为每个协作者实例化一个默认实现类的回退机制。

因为在PHP中不能给出对象类型参数的默认值,所以我必须在构造函数中完成它。以下代码是我目前使用的方法示例:

class Engine 
{ 
    private $loader; 
    private $logger; 

    public function __construct(ResourceLoader $loader = null, Logger $logger = null) 
    { 
     if ($loader == null) $loader = new DefaultResourceLoader; 
     if ($logger == null) $logger = new DefaultLogger; 

     $this->loader = $loader; 
     $this->logger = $logger; 
    } 
} 

您对此有何看法?我应该使用IoC容器吗?还是有另一种将对象类型参数赋予默认值的方法?

+0

在这种情况下,您可以使用我的小型库[ValueResolver](https://github.com/LapaLabs/ValueResolver)来更紧凑地执行此操作。 – 2015-07-09 10:48:26

回答

2

当然,您最好使用IoC/DIP容器来完成这项工作。上面的代码(if语句)增加了类的耦合。客户端类(Engine)不应该关心装载器和记录器角色的实现。这是工厂或DIP容器的工作知道这一点。通过在您的代码中放入具体的类名,并将这些类绑定在一起,使您的代码更加灵活(敏捷),可重用性更低,因此可维护性更低。

+0

感谢您的回答。你有一个好的PHP容器的任何推荐? – Franck 2008-12-18 16:06:32

0

你可以用我的小图书馆ValueResolver在这种情况下,例如:

$logger = ValueResolver::resolve($logger, new DefaultLogger); 

,不要忘记使用命名空间use LapaLabs\ValueResolver\Resolver\ValueResolver;

也有能力类型转换,例如,如果你的变量值应该是integer,所以用这个:

$id = ValueResolver::toInteger('6 apples', 1); // returns 6 
$id = ValueResolver::toInteger('There are no apples', 1); // returns 1 (used default value) 

检查docs更多的例子