如何灵活配置多版本业务流程?

说明

我先举个例子:我从家起床到学校去上课,这期间我需要做这些事情:洗漱吃饭收拾书包交通。这些事情可以做很多种排序,简单举两个:

  • 顺序1:洗漱吃饭收拾书包交通
  • 顺序2:收拾书包吃饭洗漱交通
  • 顺序3:吃饭洗漱收拾书包交通

如果我是一个做事很讲规矩的人,那么,我每天都会按照顺序1来做。
可是巧了,我是一个很随性的人,我偏要一三五按照顺序2做,二四六按照顺序3做,周日啥都不不做(躺一天)。

问题

对应到业务代码中,我们怎么去灵活的定义多个版本的业务流程呢?

砖头

我先抛个砖,希望大佬能有更好的实现方式。
首先,在controller中,定义出洗漱吃饭收拾书包交通等方法。

class Controller
{
    public function wash(){
        // 假装有业务代码
    }
    public function eat(){}
    public function packUp(){}
    public function traffic(String $kind){}
}

然后再定义一个流程变量,将顺序1放入其中:

class Controller
{
    public $assembly_line_one = [
        [
            'info' => '洗漱',
            'func' => 'wash',
            'params' => [],
        ],
        [
            'info' => '吃饭',
            'func' => 'eat',
            'params' => [],
        ],
        [
            'info' => '收拾书包',
            'func' => 'packUp',
            'params' => [],
        ],
        [
            'info' => '交通',
            'func' => 'traffic',
            'params' => ['公交'],
        ],
    ];
    public function wash(){
        // 假装有业务代码
    }
    public function eat(){}
    public function packUp(){}
    public function traffic(String $kind){}
}

此时,我是一个老实人,只会按照这一个流程执行:

class Controller
{
    ...
    public function run()
    {
        // 按照 $assembly_line_one 定义的流程顺序执行
        foreach ($this->assembly_line_one as $step) {
            $this->{$step['func']}(...$step['params']);
        }
    }
}

那如果我是一个精分呢?就可以再多定义几个$assembly_line_two$assembly_line_three等等。

class Controller
{
    ...
    public function run()
    {
        $today_assembly_line = [];
        if($today->isMonday()){
            // 周一的顺序
            $today_assembly_line = $this->assembly_line_one;
        }
        if($today->isTuesday()){
            // 周二的顺序
            $today_assembly_line = $this->assembly_line_two;
        }
        foreach ($today_assembly_line as $step) {
            $this->{$step['func']}(...$step['params']);
        }
    }
}

以上的方式还可以进行下修改升级,将func的值设置为类似SomeClass@func的形式,这样就可以指定其他类中的方法去执行(当然foreach中的代码也需要同步修改做支持)。

最后

以上仅是自己抖了个小机灵,有错误的地方还望指正。更希望各路大佬提供些更好的思路和现成的实现,我也学习一下。

再见了妈妈今晚我就要远航,别为我担心我有快乐和智慧的桨~
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 7
ShiKi

东西不入库吗?

2年前 评论
LiamHao (楼主) 2年前

考虑一些复杂的情况,你这种设计方案可能就不能很好处理了,比如,小明在天气晴的时候出行喜欢坐公交,天气阴的时候喜欢大车,而小刚则是雷打不动每天骑自行车。可以考虑自己实现一个精简的工作流引擎,其实你本身的方案就已经是一个最简的工作流的思想了。

2年前 评论
LiamHao (楼主) 2年前
liaosp 2年前

责任链模式申请出战

2年前 评论
zhangrongwang (作者) 2年前
LiamHao (楼主) 2年前
LiamHao (楼主) 2年前

策略总是需要人来做出选择的。除非用机器学习。

2年前 评论
  • 顺序 1:洗漱、吃饭、收拾书包、交通
  • 顺序 2:收拾书包、吃饭、洗漱、交通
  • 顺序 3:吃饭、洗漱、收拾书包、交通

抽象化设定

  1. 洗漱、吃饭、收拾书包、交通 每个都设定为 command
  2. 设定为 subject, 包含交通方式: 公交、骑马
  3. 设定流程为 handler 包含顺序1或顺序2或顺序3

流程

  1. 定义 subject
  2. subject 传递给 handler
  3. handler 依次执行 command
  4. 每一个command都接收同一个subject
  5. 最后结果返回给handler

希望各路大佬提供些更好的思路和现成的实现,我也学习一下。

2年前 评论

symfony/workflow 可以满足上述需求。对应 Laravel 版本的 composer 包实现 adalessa/laravel-workflow 。感兴趣的话可以研究一下。

2年前 评论
悠悠山雨 2年前
LiamHao (楼主) 2年前

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