由于您链接到的问题的解释非常广泛,我不会再为您重新定义它。相反,我将尝试通过注入示例向您展示。
class Logger {
private $__logger;
public function __construct($logger) {
$class = $logger . "Logger";
$this->$__logger = new $class();
}
public function write($message) {
$this->$__logger->write($message);
}
}
所以,在上面你有一个类Logger,你可能会用它在某处记录信息。我们并不真正关心它是如何做到的,我们只知道它会做到。
现在,我们有几种不同的日志记录可能性...
class DBLogger {
public function write($message) {
// Connect to the database and
// INSERT $message
}
}
class FileLogger {
public function write($message) {
// open a file and
// fwrite $message
}
}
class EMailLogger {
public function write($message) {
// open an smtp connection and
// send $message
}
}
现在,当我们使用我们的记录器时,我们可以通过以下任一方式来实现:
$logger = new Logger("DB");
$logger = new Logger("EMail");
$logger = new Logger("File");
我们总是以相同的方式与$logger 交互(即我们调用write($message))。包装器实例Logger 包装了实际的日志记录类并代表我们调用它的方法。
上述代码类型的更常见用途是使用配置文件来确定您的记录器是什么。例如,考虑您希望将日志记录发送到文件的情况。您可能有一个如下所示的配置:
$logging = array(
'type' => 'file',
'types' => array(
'file' => array(
'path' => '/var/log'
'name' => 'app_errors.log'
),
'email' => array(
'to' => 'webmaster@domain.com',
'from' => 'error_logger@domain.com',
'subject' => 'Major fail sauce'
),
'db' => array(
'table' => 'errors',
'field' => 'error_message'
)
)
);
您的改编课程可能如下所示:
class FileLogger {
public function __construct() {
// we assume the following line returns the config above.
$this->config = Config::get_config("logger");
}
public function write($message) {
$fh = fopen($this->config->path . '/' . $this->config->file);
fwrite($fh, $message . "\n");
fclose($fh);
}
}
我们会为其他 adapted 类做同样的事情。然后,对主 Wrapper Logger 稍作修改,我们可以使用配置数据创建正确的封装实例,并将其基于配置中定义的 type。一旦你有了类似的东西,切换到通过电子邮件进行日志记录就像在配置中更改 type 一样简单。