【发布时间】:2013-03-01 12:23:25
【问题描述】:
假设您正在编写一个“更大”的应用程序,并且您想在类中记录某些错误。现在几乎每个班级都需要访问 Logger。
一个简单的解决方案如下(PHP,但这没关系):
class SomeClass {
public function someMethod() {
// stuff ...
Logger::log("something happened");
// stuff ...
}
}
这种方法的问题是它使每个使用 Logger 的类都依赖它,并且你不能简单地在没有 Logger 的其他项目中使用相同的类。它是紧密耦合的。而且你不能在不改变SomeClass的实现的情况下改变记录消息的方式。
上述方法的“小”升级如下:
class SomeClass {
private $logger;
public function __construct(/* stuff */) {
$this->logger = LoggerFactory::getLogger();
}
public function someMethod() {
// stuff ...
$this->logger->log("something happened");
// stuff ...
}
}
这并不能真正解决问题,因为 SomeClass 现在只依赖于 LoggerFactory 并且它与它紧密耦合。这样做的好处是,LoggerFactory 现在可以返回 Logger 类的不同实例。因此,如果您想更改记录消息的方式,则无需更改 SomeClass 的实现。
另一种方法是使用依赖注入:
class SomeClass {
private $logger;
public function __construct(Logger $logger, /* stuff */) {
$this->logger = $logger;
}
public function someMethod() {
// stuff ...
$this->logger->log("something happened");
// stuff ...
}
}
现在这不会将SomeClass 耦合到任何特定类。它只需要一个实现Logger 接口的类。但我遇到的问题是,每当您创建对象时,您都需要将 Logger 实例传递给构造函数。
$object = new Position($this->logger, $x, $y);
我遇到的另一个问题是,Logger 并不是像 $x 和 $y 这样的 Position 类的一部分。它只是一个实用程序。
您如何最好地处理这种情况?在这种情况下,耦合和内聚之间的最佳折衷是什么?
【问题讨论】: