我正在尝试建立一个雄辩的模型“平台”,该模型可以以与基于驱动程序的组件相同的方式实现某些逻辑。
一般背景: 我有一个称为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
您能给我一些关于我应该看起来或编码的方式的指示吗?
答案 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);
}
}