如何处理可能需要不同参数的接口?

时间:2018-01-24 00:24:58

标签: php oop interface

我有以下界面:

observeSingleEvent

我的应用程序需要一个函数来生成一个链接以将用户重定向到。将来,我可能需要更改链接生成的方式。现在,这是我简单的FakeLinkGenerator:

interface LinkGeneratorInterface
{
    public function generateLink();
}

但是,如果将来我的链接生成需要额外的参数,那该怎么办呢?采取以下示例

class FakeLinkGenerator implements LinkGeneratorInterface
{
    public function generateLink()
    {
        return "https://stackoverflow.com";
    }
}

这需要我更改界面,这会使编码的目的失效。如果我有这个函数依赖于这个抽象class RealLinkGenerator implements LinkGeneratorInterface { public function generateLink($parameter) { // business logic with $parameter return "https://stackoverflow.com"; // may append stuff depending on my business logic } }

LinkGeneratorInterface

我也必须改变这个实现。我希望能够为此函数指定不同的public function getLink(LinkGeneratorInterface $generator) { return $generator->generateLink(); }

注意:我的链接生成可能依赖于用户输入,因此不能通过构造函数注入参数。

2 个答案:

答案 0 :(得分:1)

  

但是,如果将来我的链接生成需要额外的参数,那该怎么办呢?采取以下示例

然后您创建新方法,或者以破坏向后兼容性为代价更改您的界面。由您来决定哪种方式对您有用。

  

使编码的目的失败

你误解了界面的概念 - 它不是一个不可改变的具体块。您可以根据需要在需要时更改它。如果您认为您经常更改它,那么您的软件设计可能会有些不稳定 因为你根本没有预见到你的界面应该帮助定义的太多东西。

答案 1 :(得分:0)

这里有几个选项:

  • 可选参数

脏(我认为)这样做的方法是使用可选参数:

class FakeLinkGenerator implements LinkGeneratorInterface
{
    public function generateLink($param = 'defaultValue')
    {
        return "https://stackoverflow.com/$param";
    }
}

这将通过界面验证,并允许您在创建实现时具有很大的灵活性。当有效地使用合理的默认值时,这非常有用。什么使它小于可选是当参数不是可选的,我们只使用这个技巧来通过验证。这会导致额外的开销(此可选参数不是可选的)并且更有可能导致问题。

  • 构造函数注入

一种更简洁的方法,更简洁,因为我们保持方法签名不变,是从具体类构造函数中注入参数并在实现方法中使用它:

class FakeLinkGenerator implements LinkGeneratorInterface
{
    private $param;

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

    public function generateLink()
    {
        return "https://stackoverflow.com/{$this->param}";
    }
}

这是我首选的方法。从理论上讲,这也是一种有效的方式;接口应该定义成员,通过该成员我们与对象通信,将实现细节留给所述对象。理想情况下,我们不应该在构造函数中工作。由于这些原因,我们可以提出一个软规则,不在界面中定义构造函数的参数,让我们可以自由地使用这种方法。