【问题标题】:Giving PHP object-type arguments a default value给 PHP 对象类型参数一个默认值
【发布时间】:2010-09-27 11:09:32
【问题描述】:

我正在编写一个考虑到可测试性的 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 容器,还是有另一种方法可以为对象类型参数提供默认值?

【问题讨论】:

  • 在这种情况下,您可以使用我的小型库 ValueResolver 使其更紧凑

标签: php unit-testing dependency-injection


【解决方案1】:

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

【讨论】:

  • 感谢您的回答。你有什么好的 PHP 容器推荐吗?
【解决方案2】:

在这种情况下,您可以使用我的小型库 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 了解更多示例

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    相关资源
    最近更新 更多