【问题标题】:How to Handle different sibling objects (not models) in Laravel project如何在 Laravel 项目中处理不同的兄弟对象(不是模型)
【发布时间】:2020-12-16 07:52:57
【问题描述】:

我有一个订单控制器存储功能,它处理几种类型的订单(销售订单、采购订单等)的订单创建。这些所有订单都存储在同一个订单表中。

但每种类型的订单都有一些不同的功能。根据他们的属性。 (打印发票、发送通知等)

这些是我的问题

  1. 既然有一个订单模型,如何在 Laravel 中处理这些类型的场景?
  2. 如果我需要根据它们的类型创建单独的对象,我必须将这些类放在 Laravel 项目中吗?
  3. 如何在 Laravel 中将请求数据与这些对象进行映射?

我目前想做的是在商店功能中。 (据说我为所有这些使用了一条路线)

$order = null;
switch ($request->json('order_type')) {
    case 'sales':
        $order = new SalesOrder;
        $order->total = $request->json('total');
        ...
        break;
    case 'purchase':
        $order = new PurchaseOrder;
        $order->total = $request->json('total');
        ...
        break;
    default:
        break;
}

谢谢

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    我建议在每个场景中使用 InterfaceConcrete Class,并在创建对象时使用 Factory 模式

    1. 对于界面,您将创建一个OrderInterface
    interface OrderInterface
    {
        public function make(Request $request);
    }
    
    1. 对于你将要做的具体课程
    class Purchase implements OrderInterface
    {
    
        public function make(Request $request)
        {
           ...
        }
    }
    
    class Sales implements OrderInterface
    {
    
        public function make(Request $request)
        {
           ...
        }
    }
    
    1. 工厂用
    class OrderFactory
    {
        public static function make(string $type)
        {
            if ($type === 'sales') {
                return new Sales();
            } elseif ($type === 'purchase') {
                return new Purchase();
            }
        }
    }
    

    在你的控制器中你会这样做

    $order = OrderFactory::make($request->json('order_type'));
    $order->make($request);
    

    现在您有了一种非常简洁易读的方式来创建订单对象,这为您提供了更多的抽象和封装方式来创建对象。

    另一种解决方案 - 但它是 Laravel 的东西

    除了工厂部分我们将使用 Laravel serviceContainerBinding 所以你会这样做

    1. 在您的控制器中,您将像这样接受OrderInterface 的对象
    public function makeOrder(OrderInterface $order) {
       $order->make($request);
    }
    
    1. 在你AppServiceProvider
    $this->app->singleton(OrderInterface::class, function ($app) {
        if (request()->get('order_type') === 'sales') {
            return new Sales();
        } elseif (request()->get('order_type') === 'purchase') {
            return new Purchase();
        }
    });
    

    【讨论】:

    • 感谢您的出色回答。如何使用订单模式将创建的销售或采购订单保存在订单表中?
    • 好吧,如果我的问题正确,您将在每个相应的类中添加创建代码,例如在Sales 类中添加public function make(Request $request) { $order = new SalesOrder; $order->total = $request->json('total'); ... }
    • 哦..现在我明白了
    • 我修改了您的第一个解决方案。在不使用接口的情况下,我使用了一个名为“order”的抽象类。因为订单类型中有一些可重用的功能。将 make 函数保持为抽象。会好吗?
    • 是的,完全没问题,当您的子类具有公共共享方法时,这就是使用抽象的地方,因此您将在抽象 order 中定义这些方法。
    猜你喜欢
    • 2018-09-08
    • 2014-04-11
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    相关资源
    最近更新 更多