PHP - 使用空接口来确定逻辑

时间:2012-10-12 22:07:38

标签: php oop interface

有几个地方我根据类实现的接口执行逻辑 - 有什么理由可能会出错也可能没出错? (感觉很脏)

这样做的原因是你不必添加任何类属性或方法来确定这些东西,基本上在类定义中你可以明确说明它能做什么/不能做什么。

一个用例是ajax调用,有些需要你登录,有些则不需要:

class ajax_ads extends ajax_controller implements no_login {

}

此外,界面中没有方法,为此目的使用了它。

interface no_login {}

然后在基本控制器中:

$controller = controller::factory()
if( !($controller instanceof no_login) && !$controller->LoggedIn()){
    return $controller->redirect(/*login page*/); 
}

使用instance_of看起来轻巧简单,它工作正常,但再次感觉我完全滥用界面的目的。

所以我问,是用一个接口来判断逻辑是个坏主意,糟糕的oop还是'好吧'?

3 个答案:

答案 0 :(得分:7)

当您需要ifswitch来确定对象应该处于的状态时,通常一个好的迹象表明您需要多态

在您的情况下,应该有一个抽象类:Ajax_Ads和两个扩展类:No_Login_Ajax_Ads extends Ajax_AdsLogin_Ajax_Ads extends Ajax_Ads。然后根据程序的状态实例化您需要的那个,这可以通过工厂完成。

有关详细信息,请观看以下讲座: The Clean Code Talks -- Inheritance, Polymorphism, & Testing

答案 1 :(得分:0)

我不知道有任何缺点,但感觉就像是误用了界面语法。为什么不在ajax_ads中实现一个简单的方法:

class ajax_ads
{
    ...
    public function requiresLogin() { return false; }
}

然后替换

if ($controller instanceof no_login) ...

通过

if (!$controller->requiresLogin()) ...

这种方法可以缩短到与trait几乎相同的简洁。

答案 2 :(得分:0)

接受的答案是 2012 年的。Laravel 今天使用空接口模式,所以我会说它没问题。

<?php

namespace Illuminate\Contracts\Queue;

interface ShouldQueue
{
    //
}

https://github.com/laravel/framework/blob/8.x/src/Illuminate/Contracts/Queue/ShouldQueue.php

protected function sendMailable(MailableContract $mailable)
{
    return $mailable instanceof ShouldQueue
                    ? $mailable->mailer($this->name)->queue($this->queue)
                    : $mailable->mailer($this->name)->send($this);
}

https://github.com/laravel/framework/blob/8.x/src/Illuminate/Mail/Mailer.php#L300(第 300-305 行)