使用适配器模式和类型提示的依赖注入

时间:2018-02-07 13:04:46

标签: php oop design-patterns

我试图与适配器结合使用类型暗示。

系统通过不同的服务获取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。

我在这里做错了吗?

1 个答案:

答案 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);
}

注意:还要检查命名空间