我试图与适配器结合使用类型暗示。
系统通过不同的服务获取XML提要并使用更改更新数据库 - 我正在重构以帮助学习设计模式。
日志界面:
interface LoggerAdapterInterface {
public function debug($string);
public function info($string);
public function error($string);
}
MonoLog适配器
class MonoLogAdapter implements LoggerAdapterInterface
{
public $logger;
public function __construct(\Monolog\Logger $logger)
{
$this->logger = $logger;
}
public function debug($string)
{
$this->logger->debug($string);
}
public function info($string)
{
$this->logger->info($string);
}
public function error($string)
{
$this->logger->error($string);
}
}
FeedFactory
class FeedFactory
{
public function __construct()
{
}
public static function build(LoggerAdapter $logger, $feedType)
{
// eg, $feedType = 'Xml2u'
$className = 'Feed' . ucfirst($feedType);
// eg, returns FeedXml2u
return new $className($logger);
}
}
实施
// get mono logger
$monoLogger = $this->getLogger();
// create adapter and inject monologger
$loggerAdapter = new MonoLogAdapter($monoLogger);
// build feed object
$Feed = FeedFactory::build($loggerAdapter, 'Xml2u');
错误
PHP Catchable fatal error: Argument 1 passed to FeedFactory::build()
must be an instance of LoggerAdapter, instance of MonoLogAdapter
given, called in /src/shell/feedShell.php on line 64 and defined in
/src/Feeds/FeedFactory.php on line 25
所以我使用的是LoggerAdapter,因此我没有使用一个日志记录平台。问题是,当我创建一个新的MonoLogger实例并尝试将其注入工厂时 - PHP类型提示没有意识到MonoLogger实现了LoggerAdapter。
我在这里做错了吗?
答案 0 :(得分:2)
正如@Ironcache建议的那样 - 在build
方法中使用interface作为参数。
public static function build(LoggerAdapterInterface $logger, $feedType)
{
// eg, $feedType = 'Xml2u'
$className = 'Feed' . ucfirst($feedType);
// eg, returns FeedXml2u
return new $className($logger);
}
注意:还要检查命名空间