在Laravel中建立一个“基于驱动程序”的模型

时间:2019-10-06 17:01:59

标签: laravel eloquent

我正在尝试建立一个雄辩的模型“平台”,该模型可以以与基于驱动程序的组件相同的方式实现某些逻辑。

一般背景: 我有一个称为Platforms的laravel模型,该模型具有一些通用方法。但是根据确切的“平台”,我想构建一些自定义方法,这些方法仅适用于该特定平台。它可能类似于连接方法或类似方法。

所以我的方法是像基于驱动程序的组件那样做,扩展了Illuminate\Support\Manager,因为我需要方法上的某种契约。而且我希望在加载特定的“平台”后可以使用这些方法。

我知道我可以在模型本身中编写每个方法,或者为每个平台包含类似处理方法的代码。最终,我将拥有大约10个平台,以及大约5种自定义方法,因此它将变得非常丑陋。

我不想将其构建为组件,因为我需要与其他模型的关系。

另一种解释方式可能是这样的: 假设您有一堆可以从应用程序中获取SMS通知的用户,然后用户可以选择必须使用的SMS“提供者”。 (例如,像Nexmo),那么它将是class SMSProvider extends model 具有某些方法,例如send 这样一来,您可以$user->SMSProvider->send()

此发送方法必须特定于特定的提供者,就像在文档中https://laravel.com/docs/6.x/notifications#sms-notifications

您能给我一些关于我应该看起来或编码的方式的指示吗?

1 个答案:

答案 0 :(得分:1)

要做答案,我必须对解决方案承担很多责任。设置了基础,您需要一个平台模型,假设它具有指示提供者的类型。

/**
 * @property string type
 */
public class Platform extends Model
{
    ...
}

驱动程序方法主要是在外部人员应该扩展您的库的情况下完成的,并且是用于不同实现的一种管理工具。没错,但是我觉得它比应该的要复杂。直接的方法是将平台的类型绑定到实现。为实现创建一个接口。

public interface SMSProvider
{
    public function sendSMS(): void;
}

为了演示起见,一个实现。

public class TeliaSMSProvider implements SMSProvider
{
    public function sendSms(): void
    {
        // magic
    }
}

在您的应用服务提供商中,将您的输入绑定到该应用。

$this->app->bind('telia', function ($app) {
    return new TeliaSMSProvider();
});

同样,此绑定部分只是在类型和基于type参数的正确实例,驱动程序或方法调用之间建立连接的一种简便方法。

现在只需从平台加载您的提供程序,并将类型作为输入即可。键入提示以便于使用。

public class Platform extends Model
{
    public function getProvider(): SMSProvider
    {
        return app($this->type);
    }
}