构造函数注入 - 如果构造函数中没有提供,则可以使用新的null对象吗?

Flu*_*ffy 6 php language-agnostic dependency-injection

想象一下,我有一堆类可以进行日志记录,所以我创建了一个logger接口和几个实现(写入文件,stdout,db等),但有时我不关心日志记录这些消息,所以我做了一个实现,只是忽略了所有的消息.

现在这有助于避免if使用s $this->logger->write($message),但我仍然必须每次都注入虚拟记录器.

因此$this->logger = $logger ? $logger : new DummyLogger(),在构造函数中执行以下操作会造成任何伤害.

我通常在构造函数中没有工作,但这种东西似乎并不太危险.

你会选择这种方法吗?

Gor*_*don 1

在回答您的问题之前,我建议重新考虑您的 Logger 架构。日志记录始终是相同的。你写一条消息到某个地方。唯一不同的是某处部分,因此将 Logger 分为通用 Logger 和各种 Writer 是有意义的。这提供了更大的灵活性,例如,您可以使用复合模式一次写入多个记录器。

关于您的问题:一般来说,您希望避免将依赖项硬编码到代码中,因为它将直接影响可测试性和可重用性,例如您的 Logger 只能与这个特定的 NullWriter 一起使用。如果您要分发 Logger,您还必须分发 Writer。

然而,假设您无论如何都只会将 Logger 与整个 Writer 包一起分发,并且您还提供了执行 ctor 注入的方法,那么我认为没有什么问题。如果需要,您仍然可以更换 Writer,所以一切都很好。

当我们谈论包间依赖关系时,情况有些不同。您将希望避免这些,例如,Database 包中的类不应依赖于 Logger 包中的类。

从 Logger 内部分配 NullWriter 的另一种方法是使用 LoggerFactory 来创建 Logger 和指定的 Writer、注入 Writer 并返回 Logger。