Laravel-扎实的原则

Bor*_*rov 4 php laravel

我想问您有关Laravel中的SOLID原则,特别是关于接口隔离原则的问题。

假设我们有一个应用程序,用户可以在其中发送订单。但是对于每个用户,我们都有不同的发送订单的方式。例如,用户一-通过电子邮件发送订单。用户二-通过xml发送的命令上传到ftp。在php中,我们可以创建以下接口:

<?php
interface ISendOrder
{
    public function sendOrder(); 
}
Run Code Online (Sandbox Code Playgroud)

然后针对每个特定用户实施它。但是在Laravel中,我们只有一个类User。假设用户具有用户类型的属性,从中可以找到sendOrder类型。在Laravel中执行此操作的最佳方法是什么?也许是一个开关/如果找到并返回正确的实现,或者有更好的方法?

Moz*_*mil 8

感觉这是战略模式的一个很好的用例。在您的示例中,用户可以通过多种方式发送订单。换句话说,多种策略。现在也是考虑将您的订购逻辑添加到服务层的好时机。

诚然,您的问题有点含糊,但我将尝试举例说明如何完成此任务。因此,假设您的App\User模型将实现interface ISendOrder

use App/Services/Order/OrderService; 
use App/Services/Order/ISendOrder;

class User extends Authenticatable implements ISendOrder 
{
    protected $orderStrategies = [
        'standard' => App/Services/Order/Strategies/StandardStrategy::class, 
        'vip' => App/Services/Order/Strategies/VipStrategy::class
    ];

    public function sendOrder(Order $order, OrderService $service)
    {
        $service->setStrategy($this->orderStrategies[$this->type]); 

        return $service->sendOrder($this, $order); 
    }
}
Run Code Online (Sandbox Code Playgroud)

您的一个非常简单的示例OrderService如下所示:

class OrderService 
{
    protected $strategy; 

    public function setStrategy(OrderStrategy $strategy)
    {
        $this->strategy = $strategy; 
    }

    public function sendOrder(ISendOrder $user, Order $order)
    {
        // logic to send order 
        // $this->strategy holds the strategy to be used
    }
}
Run Code Online (Sandbox Code Playgroud)

此步骤是完全可选的,但我可能会将订单发送逻辑封装为特征。您的模型看起来会干净很多。此外,您可以轻松地将此逻辑添加到models将来可能发送订单的任何其他逻辑中。

class User extends Authenticatable implements ISendOrder 
{
    use InteractsWithOrder;
}
Run Code Online (Sandbox Code Playgroud)

您的特征将如下所示:

trait InteractsWithOrder
{
    protected $orderStrategies = [
        'standard' => App/Services/Order/Strategies/StandardStrategy::class, 
        'vip' => App/Services/Order/Strategies/VipStrategy::class 
    ];

    public function sendOrder(Order $order, OrderService $service)
    {
        $strategy = new $this->orderStrategies[$this->type]; 

        $service->setStrategy($strategy); 

        return $service->sendOrder($this, $order); 
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个很小的例子来说明如何,你可以可能完成这件事。