13

我正在开发一个正在注入 Logger 对象的服务,但我可以拥有 2 种不同类型的记录器,我计划拥有一个 syslog 记录器和一个队列消息系统记录器。这可能吗?

这个想法是有一个接口:

interface Loggable
{
    public function log() ;
}

和 2 个实现该接口的类:

class Syslogger implements Loggable
{
    public function log()
    {
        ...
    }
}

class QMSLogger implements Loggable
{
    public function log($queueName)
    {
        ...
    }
}

我能想到的唯一方法是将数组作为参数并在一个类上使用它而不在另一个类上使用......但这有点臭:P

4

4 回答 4

21

你问是否有可能:是的,但是……</p>

如果你实现一个接口,你必须尊重它的契约

interface Loggable
{
    public function log();
}

这个接口的约定是你可以log()在没有任何参数的情况下调用。

为了尊重这一点,您可以将参数设为可选:

class QMSLogger implements Loggable
{
    public function log($queueName = null)
    {
        ...
    }
}

这是完全有效的 PHP,它尊重 Liskov 替换原则。当然,在对 interface 进行编码时,您不能使用该可选参数,否则您显然会破坏 interface。这样的参数只有在您使用实现时才有用(例如,在与QMSLogger.

但是,这可能不是您的问题的解决方案,因为它$queueName似乎是一个配置值,最好将它传递给类的构造函数(如另一个答案中所述)。

于 2015-10-13T19:45:18.117 回答
18

如评论中所述,这不是同一个界面。如果您无法在所有可能的记录器实现中通用接口,请将配置差异作为实例构造函数的一部分:

class QMSLogger implements Loggable {

    protected $queueName;

    public function __construct($queueName) {
        $this->queueName = $queueName;
    }

    public function log() {
        ...
    }

}
于 2012-12-20T10:46:51.003 回答
5

我遇到了一个类似的情况,我想创建一个接口,它只是确保实现它的任何类都有一个同名的方法,但允许使用不同的参数实现。

/**
 * Interface Loggable
 * @method log
 */
interface Loggable
{

}

现在 Loggable 接口可以用不同的参数来实现,就像这样。

class Syslogger implements Loggable
{
    public function log($key, $value)
    {
        ...
    }
}
于 2020-01-24T18:28:42.470 回答
1

您也可以将参数作为数组传递,这样您一方面尊重合同,还可以灵活地在数组内插入任何数量的任何值,检查一下:

abstract class FeaturesAbstract
{
    /**
     * @param array $paramsArray
     *
     * @return mixed
     */
    abstract public function addExecute($paramsArray);
}

要实际使用此方法,您可以发送如下参数:

$this->abstract->addExecute(array('paramA' => $paramA, 'paramB' =>  $paramB));

然后在具体实现中,您将获得如下参数:

    /**
     * @param array $paramsArray
     *
     * @return void
     */
    public function addExecute($paramsArray) 
    {
        $a = $paramsArray['paramA'];
        $b = $paramsArray['paramB'];
        $c = ...
    }

祝你好运 :)

于 2016-10-07T13:32:25.057 回答