8

有几个地方我根据类实现的接口执行逻辑 - 有什么理由表明这可能是错的,也可能不是错的?(感觉很脏)

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

一种用例是 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 还是“好的”?

4

3 回答 3

8

当您需要 aif或 aswitch来确定对象应该处于的状态时,这通常是您需要polymorphism的好兆头。

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

欲了解更多信息,请观看以下讲座:清洁代码会谈——继承、多态性和测试

于 2012-10-12T22:10:33.733 回答
1

接受的答案来自 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行)

于 2021-04-13T05:20:49.760 回答
0

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

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

然后替换

if ($controller instanceof no_login) ...

经过

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

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

于 2012-10-12T22:12:22.127 回答