【问题标题】:Build a "driver-based" model in Laravel在 Laravel 中构建“基于驱动程序”的模型
【发布时间】:2019-10-15 05:48:37
【问题描述】:

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

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

所以我的方法是像基于驱动程序的组件一样,扩展Illuminate\Support\Manager,因为我需要某种方法上的合同。而且我希望这些方法在我加载特定的“平台”时可以访问。

我知道我可以在模型本身中编写每个方法,或者包含每个平台的句柄方法。最后,我将拥有大约 10 个平台,大约 5 个自定义方法,所以它会很快变得丑陋。

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

另一种解释方式可能是这样的: 假设您有一群用户可以从应用程序接收短信通知,然后用户可以选择必须使用的短信“提供者”。 (例如 Nexmo)这将是 class SMSProvider extends model 其中有某些方法,如send 这样你就可以做到$user->SMSProvider->send()

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

你能给我一些关于我应该以哪种方式查看或编码的指示吗?

【问题讨论】:

  • 如果您将在“app/Models/”和“app/Models/SubPlatforms/”中拥有例如平台模型,您将拥有一些特定平台怎么办?在这种情况下,您可以仅在平台模型中编写一些核心功能,并为每个模型编写其他特定功能。该子模型将作为平台的扩展模型。您对此有何看法..
  • 我认为类似的解决方案会更容易,只需创建一个通用方法将平台类型映射到实现它的类?当我看到这个问题时,它更多的是关于代码分离和清洁度?
  • 它将如何“加载”特定的子平台。在我的示例中,我总是通过关系加载平台,例如 $user->platform->specificMethod()?
  • 今晚我会给出答案 :) 我可能也可以让它与 Manager 类一起工作。
  • @mrhn 可能的答案有什么进展吗?

标签: laravel eloquent


【解决方案1】:

在回答问题时,我必须对解决方案做出很多假设。基础已经确定,您需要一个 Platform 模型,假设它具有指示提供者的类型。

/**
 * @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();
});

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

现在只需从平台加载您的提供程序,并将类型作为输入。打字提示更容易使用。

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

【讨论】:

  • 所以为了使用自定义方法,我会这样做:
  • $platform = Platform::find(1); $platform->getProvider()->sendSms();这意味着您有某种类型的列,指示您要使用的短信提供商。
  • 抱歉打扰了,我的编辑时间窗口已过。加载模型后,有没有办法“自动加载”方法?
  • 你可以重写调用方法,或者在平台中创建一个助手。公共函数 sendSms() { $this->getProvider()->sendSms(); }
猜你喜欢
  • 1970-01-01
  • 2016-01-27
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
相关资源
最近更新 更多