一个 Pipeline 的使用场景

背景

比如现在要设计一个用户贷款能力评估的一个系统,需要根据用户的状况和条件计算用户的贷款分值。

实现部分

从 if else 和 使用 Pipeline 进行比较:

用户实例:

$user = [
    'credit_value' => 100, // 芝麻信用分
    'have_car' => true, // 是否有车
    'car_value' => 30, // 车子的价值多少万
    'is_marray' => false, // 是否结婚
    'have_home' => false, // 是否有房子
];

ifelse 实现

func creditAssess($user)
{
    $credit = 0;

    // 芝麻信用
    if ($user['credit_value'] >= 550) {
        $credit += 300;
    } elseif ($user['credit_value'] >= 300) {
        $credit += 150;
      } elseif ($user['credit_value'] >= 100) {
        $credit += 50;
      } else {
        $credit += 0;
      }

      // 车子评估
      ....

      // 婚姻评估
      ...

      // 其他维度
      ...
}

Pipeline 实现

index.php

$user = [
    'credit_value' => 100,
    'have_car' => true,
    'car_value' => 30,
    'is_marray' => false,
    'have_home' => false,
];

$pipes = [
    PersonalCreditAssess::class,
    MarrayAssess::class,
    HomeAssess::class,
    CarAssess::class,
];

$credit = (new Pipeline(app()))
    ->send($user)
    ->through($pipes)
    ->then(function(array $user) {
        return 0;
    });

dd($credit);

芝麻信用:PersonalCreditAssess

class PersonalCreditAssess
{
    public function handle($user, $next)
    {
        $credit = 0;

        if ($user['credit_value'] >= 550) {
            $credit = 300;
        } elseif ($user['credit_value'] >= 300) {
            $credit = 150;
        } elseif ($user['credit_value'] >= 100) {
            $credit = 50;
        } else {
            $credit = 0;
        }

        $nextCredit = $next($user);

        return $credit + $nextCredit;
    }
}

婚姻部分:MarrayAssess

class MarrayAssess
{
    public function handle($user, $next)
    {
        $credit = 0;

        if ($user['is_marray']) {
            $credit = 100;
        }

        return $next($user) + $credit;
    }
}

房子评估:HomeAssess

class HomeAssess
{
    public function handle($user, $next)
    {
        $credit = 0;

        if ($user['have_home']) {
            $credit = 300;
        }

        return $next($user) + $credit;
    }
}

等等,其它部分

总结

我们可以看到,Pipeline 将代码变得优雅,从庞大的 if else 中解脱出来,以及对以后的用户其它维度做到了方便的扩展,是 “对修改关闭,有扩展开放” 的设计原则体现。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 1年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5
Mumujin

应该是

return (new Pipeline(app()))
    ->send($request)
    ->through(array_filter([
        $pipes
    ]))->then(fn ($request) => app()->make(YouResponse::class));

原因是在 Laravel 可直接使用 $reqeust->user() 可获取当前用户信息。在 Through 方法使用 array_filter 表示可以动态策略。

一般结束我们可直接返回 Response 可参考 Illuminate\Contracts\Support\Responsable 接口,以及在 LaravelException\Hander@render

public function render($request, Throwable $e)
    {
    // ...

        if ($e instanceof Responsable) {
            return $e->toResponse($request);
        }
        // ... ...
}
1年前 评论

建议命名:
结婚:marryis_married
房子:househas_house
:see_no_evil:

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!