简介

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

角色

  • 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 > DogClient: 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 > DogClient: 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.

本文由mdnice多平台公布