「责任链模式」栗子

<?php

/**
 * 假设有一个复杂的判断流程,检查一个人是否符合参加某项比赛的条件
 * 条件包括:
 *   1. 年龄必须大于等于18岁;
 *   2. 身高必须大于等于170cm;
 *   3. 体重必须在60kg~80kg之间;
 *   4. 必须有一定的运动能力,包括50米短跑必须在10秒以内、100米游泳必须在2分钟以内、50米自行车骑行必须在15秒以内。
 */
interface Handler
{
    public function handle($request);
}

abstract class AbstractHandler implements Handler
{
    protected $successor;

    public function setSuccessor(Handler $successor)
    {
        $this->successor = $successor;
    }

    public function handle($request)
    {
        if ($this->process($request) && $this->successor) {
            $this->successor->handle($request);
        }
    }

    abstract protected function process($request);
}

class AgeHandler extends AbstractHandler
{
    protected function process($request)
    {
        if ($request['age'] < 18) {
            echo "年龄必须大于等于18岁。";
            return false;
        }

        return true;
    }
}

class HeightHandler extends AbstractHandler
{
    protected function process($request)
    {
        if ($request['height'] < 170) {
            echo "身高必须大于等于170cm。";
            return false;
        }

        return true;
    }
}

class WeightHandler extends AbstractHandler
{
    protected function process($request)
    {
        if ($request['weight'] < 60 || $request['weight'] > 80) {
            echo "体重必须在60kg~80kg之间。";
            return false;
        }

        return true;
    }
}

class SkillHandler extends AbstractHandler
{
    protected function process($request)
    {
        if ($request['running'] > 10 || $request['swimming'] > 120 || $request['biking'] > 15) {
            echo "必须有一定的运动能力,包括50米短跑必须在10秒以内、100米游泳必须在2分钟以内、50米自行车骑行必须在15秒以内。";
            return false;
        }

        return true;
    }
}

$ageHandler = new AgeHandler();
$heightHandler = new HeightHandler();
$weightHandler = new WeightHandler();
$skillHandler = new SkillHandler();

$ageHandler->setSuccessor($heightHandler);
$heightHandler->setSuccessor($weightHandler);
$weightHandler->setSuccessor($skillHandler);

$request = [
    'age' => 18,
    'height' => 170,
    'weight' => 90,
    'running' => 11,
    'swimming' => 110,
    'biking' => 14
];

$ageHandler->handle($request);
本作品采用《CC 协议》,转载必须注明作者和本文链接
悲观者永远正确,乐观者永远前行。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 7

你这个不如写个观察者模式了

1年前 评论
MArtian (楼主) 1年前

这个责任链实现的有点瑕疵:

$ageHandler
->setSuccessor($heightHandler)
->setSuccessor($weightHandler)
->setSuccessor($skillHandler);

这样更好

1年前 评论

累不累啊

$arr = [
            AgeHandler::class,
            HeightHandler::class,
            WeightHandler::class,
            SkillHandler::class,
        ];
        foreach ($arr as $item) {
            $class = new $item;
            if (!$class->handle($request)) {
                new Exception('error');
            }
        }
1年前 评论

Laravel 中的 Pipeline 是不是就是用了这种责任链模式?

11个月前 评论
MArtian (楼主) 11个月前
zerocoder (作者) 11个月前

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