假设您正在编写一个“更大”的应用程序,并且您想在类中记录某些错误。现在几乎每个班级都需要访问 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 并不是真正的Position
类的一部分,例如$x
and $y
。它只是一个实用程序。
你如何最好地处理这种情况?在这种情况下,耦合和内聚之间的最佳折衷是什么?