laravel 策略模式、工厂模式使用案例

laravel 策略模式、工厂模式使用案例

在 Laravel 中使用设计模式来对接多个物流服务商(如菜鸟、顺丰、极兔),可以使用 策略模式工厂模式 来实现动态调用不同物流接口的功能。下面的示例展示了如何使用策略模式来实现这个需求,通过一个父类,多个子类来处理不同的物流服务商,并根据单号选择对应的物流服务商。

步骤

  1. 定义物流接口(父类):定义物流接口,所有物流服务商都必须实现该接口。
  2. 定义各个物流服务商的子类:每个物流服务商继承父类并实现特定的物流接口逻辑。
  3. 编写服务工厂类:根据传入的物流单号选择合适的物流服务商类。
  4. 使用依赖注入调用相应物流服务商

1. 定义物流接口

app/Services/Shipping/ShippingServiceInterface.php 中定义接口。

copy
namespace App\Services\Shipping;

interface ShippingServiceInterface
{
    public function track($trackingNumber);
}

2. 实现各个物流服务商(子类)

app/Services/Shipping/ 目录下,为每个物流公司创建一个类。

菜鸟物流类

copy
namespace App\Services\Shipping;

class CainiaoShippingService implements ShippingServiceInterface
{
    public function track($trackingNumber)
    {
        // 菜鸟物流的具体查询逻辑
        return "Tracking Cainiao package: " . $trackingNumber;
    }
}

顺丰物流类

copy
namespace App\Services\Shipping;

class SFShippingService implements ShippingServiceInterface
{
    public function track($trackingNumber)
    {
        // 顺丰物流的具体查询逻辑
        return "Tracking SF package: " . $trackingNumber;
    }
}

极兔物流类

copy
namespace App\Services\Shipping;

class JituShippingService implements ShippingServiceInterface
{
    public function track($trackingNumber)
    {
        // 极兔物流的具体查询逻辑
        return "Tracking Jitu package: " . $trackingNumber;
    }
}

3. 创建物流服务工厂类

app/Services/Shipping/ShippingServiceFactory.php 中创建一个工厂类,负责根据单号选择对应的物流服务商。

copy
namespace App\Services\Shipping;

class ShippingServiceFactory
{
    public function getShippingService($trackingNumber)
    {
        // 根据 trackingNumber 判断使用哪个物流服务商
        if (strpos($trackingNumber, 'CN') === 0) {
            return new CainiaoShippingService();
        } elseif (strpos($trackingNumber, 'SF') === 0) {
            return new SFShippingService();
        } elseif (strpos($trackingNumber, 'JT') === 0) {
            return new JituShippingService();
        } else {
            throw new \Exception('No matching shipping service found.');
        }
    }
}

4. 在控制器中调用

app/Http/Controllers/ShippingController.php 中编写控制器,调用物流服务。

copy
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\Shipping\ShippingServiceFactory;

class ShippingController extends Controller
{
    protected $shippingFactory;

    public function __construct(ShippingServiceFactory $shippingFactory)
    {
        $this->shippingFactory = $shippingFactory;
    }

    public function trackPackage($trackingNumber)
    {
        try {
            // 根据单号选择对应的物流服务
            $shippingService = $this->shippingFactory->getShippingService($trackingNumber);
            $trackingInfo = $shippingService->track($trackingNumber);

            return response()->json([
                'status' => 'success',
                'data' => $trackingInfo
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => $e->getMessage()
            ], 400);
        }
    }
}

5. 路由

routes/web.php 中添加路由:

copy
use App\Http\Controllers\ShippingController;

Route::get('/track/{trackingNumber}', [ShippingController::class, 'trackPackage']);

6. 依赖注入配置(可选)

为了更方便使用 Laravel 的依赖注入机制,你可以在 AppServiceProvider 中将服务工厂类注册为单例。

copy
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\Shipping\ShippingServiceFactory;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(ShippingServiceFactory::class, function ($app) {
            return new ShippingServiceFactory();
        });
    }

    public function boot()
    {
        //
    }
}

使用

你可以通过访问 /track/{trackingNumber} 来测试。例如:

  • /track/CN123456 使用菜鸟物流
  • /track/SF123456 使用顺丰物流
  • /track/JT123456 使用极兔物流

总结

通过使用策略模式(结合工厂模式),你可以轻松对接多个物流服务商,并根据物流单号选择合适的服务。

posted @   pine007  阅读(106)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示

目录导航