強力な依存性注入を中心に構築されたシステムでは、次のような不自然な状況にどのように対処すればよいか疑問に思っています。
<?php
class LogWriter
{
public function write(Log $log)
{
echo $log->getMessage();
}
}
class Log
{
private $message;
public function setMessage($message)
{
$this->message = $message;
}
public function getMessage()
{
return $this->message;
}
}
class Logger
{
private $writer;
public function __construct(LogWriter $writer)
{
$this->writer = $writer;
}
public function write($message)
{
// Here is the dependency
$log = new Log();
$log->setMessage($message);
$this->writer->write($log);
}
}
Logger::write() メソッドは Log のインスタンスを作成し、それをログ ライターに渡します。私の直感では、それは悪いアプローチであり、今から 1 か月後に関連するバグを追跡する予定であり、テスト中に Log クラスを別のものに切り替えたいと思うかもしれません。
しかし、それを回避する方法は?頭に浮かぶ唯一のことは、 Logタイプを Logger コンストラクターに渡し、 Logger クラスを次のように変更することです。
class Logger
{
private $writer;
private $log_type;
public function __construct(LogWriter $writer, $log_type)
{
$this->writer = $writer;
$this->log_type = $log_type;
}
public function write($message)
{
$log = new $this->log_type();
$log->setMessage($message);
$this->writer->write($log);
}
}
そして、次のように新しい Logger インスタンスを作成します。
$log_writer = new LogWriter();
$logger = new Logger($log_writer, "Log");
しかし、それは少しハックな気がします。では、このようなマイクロ依存関係にどのように対処しますか?
注: 例としてロギング クラスを使用していますが、この正確な問題の解決策を探しているわけではありません。おそらく、Log クラスの代わりに配列を使用するだけです。
編集:より複雑な状況では、依存性注入コンテナーを Logger クラスに渡し、それを使用して Log のインスタンスを作成することもできますが、単純なロガー クラスの場合は複雑すぎるようです。