写点什么

行为型设计模式 - 责任链 Chain Of Responsibility

作者:菜皮日记
  • 2023-09-08
    北京
  • 本文字数:1697 字

    阅读完需:约 6 分钟

简介

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

角色

  • Handler 接口

    定义处理方法签名,设置 nextHandler 方法

  • Concrete Handler 具体类

    实现各自 handler 逻辑

  • BaseHandler 封装一层 handler,可有可无

类图

如图,在 client 中,将 handler 一个个串起来,每个 handler 处理完后可决定是否向后传递。

类图

代码

interface Handler{    public function setNext(Handler $handler): Handler;
    public function handle(string $request): string;}
abstract class AbstractHandler implements Handler{    private $nextHandler;
    public function setNext(Handler $handler): Handler    {        $this->nextHandler = $handler;                return $handler;    }
    public function handle(string $request): string    {        if ($this->nextHandler) {            return $this->nextHandler->handle($request);        }
        return "";    }}
class MonkeyHandler extends AbstractHandler{    public function handle(string $request): string    {        if ($request === "Banana") {            return "Monkey: I'll eat the " . $request . ".\n";        } else {            return parent::handle($request);        }    }}
class SquirrelHandler extends AbstractHandler{    public function handle(string $request): string    {        if ($request === "Nut") {            return "Squirrel: I'll eat the " . $request . ".\n";        } else {            return parent::handle($request);        }    }}
class DogHandler extends AbstractHandler{    public function handle(string $request): string    {        if ($request === "MeatBall") {            return "Dog: I'll eat the " . $request . ".\n";        } else {            return parent::handle($request);        }    }}
function clientCode(Handler $handler){    foreach (["Nut", "Banana", "Cup of coffee"] as $food) {        echo "Client: Who wants a " . $food . "?\n";        $result = $handler->handle($food);        if ($result) {            echo "  " . $result;        } else {            echo "  " . $food . " was left untouched.\n";        }    }}
$monkey = new MonkeyHandler();$squirrel = new SquirrelHandler();$dog = new DogHandler();
$monkey->setNext($squirrel)->setNext($dog);
echo "Chain: Monkey > Squirrel > Dog\n\n";clientCode($monkey);
echo "\nSubchain: Squirrel > Dog\n\n";clientCode($squirrel);
复制代码

output:

Chain: Monkey > Squirrel > Dog
Client: Who wants a Nut?  Squirrel: I'll eat the Nut.Client: Who wants a Banana?  Monkey: I'll eat the Banana.Client: Who wants a Cup of coffee?  Cup of coffee was left untouched.
Subchain: Squirrel > Dog
Client: Who wants a Nut?  Squirrel: I'll eat the Nut.Client: Who wants a Banana?  Banana was left untouched.Client: Who wants a Cup of coffee?  Cup of coffee was left untouched.
复制代码


用户头像

菜皮日记

关注

全干程序员 2018-08-08 加入

还未添加个人简介

评论

发布
暂无评论
行为型设计模式-责任链 Chain Of Responsibility_设计模式_菜皮日记_InfoQ写作社区