前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >php设计模式(十五):职责链模式(Chain of Responsibility)

php设计模式(十五):职责链模式(Chain of Responsibility)

作者头像
高久峰
发布2023-09-18 15:38:42
1640
发布2023-09-18 15:38:42
举报

责任链模式

责任链模式又称为:职责链模式、命令链、CoR、Chain of Command、Chain of Responsibility。责任链是一种行为设计模式,允许将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。

问题

假设我们需要开发一个线下“PHP设计模式”培训课,办一个班,需要政府审批。

所以我们去了当地县教育局,县教育局回复说:“你们这个是要开一个培训学校,我们这不管新开,你去市教育局看看”;理所当然我们到了市教育局,“啊,你们要开一个培训学校呀?这个我们没有这个权限,需要去省教育局”市教育局工作人员介绍到;我们又去了省教育局,这回没有走错了,“你把你们培训什么内容以及办学规模,填表就可以等结果了”省教育局工作人员介绍到。

这样我们可能会一个函数中,我们每次去一个地,我们都需要记录,而每次新增功能都会使其更加 臃肿(代码变得越来越多,也越来越混乱)。修改某个 审批步骤 有时会影响其他的 审批步骤。最糟糕的是,系统会变得让人非常费解,而且其维护成本也会激增。在艰难地和这些代码共处一段时间后,有一天终于决定对整个系统进行重构。

解决方法

在上述示例中我们要一级级去问,能不能使用一个统一方法,自动一级级去问,只到有地方可以答应为主,每个 审批步骤 都可被抽取为仅有单个方法的类,并执行检查操作。请求及其数据则会被作为参数传递给该方法。

将这些处理者连成一条链。链上的每个处理者都有一个成员变量来保存对于下一处理者的引用。除了处理请求外,处理者还负责沿着链传递请求。请求会在链上移动,直至所有处理者都有机会对其进行处理。

请求
请求

处理者(教育局)接收到请求后自行决定是否能够对其进行处理。如果自己能够处理,处理者就不再继续传递请求。因此在这种情况下,每个请求要么最多有一个处理者对其进行处理,要么没有任何处理者对其进行处理。

结构

Handler:责任链接口基类; BaseHandler :实现 Handler 接口的抽象责任链类(可有可无); *EducationBureau:具体的责任链类 示例中指:县教育局、市教育局、省教育局;

代码示例

接口

代码语言:javascript
复制
interface Handler
{
    /**
     * 下一个请求
     * @return mixed
     * @author chendashengpc
     */
    public function setNext(Handler $handler);

    /**
     * 当前处理
     * @return mixed
     * @author chendashengpc
     */
    public function handler();
}

PHP

Copy

抽象类

代码语言:javascript
复制
abstract class BaseHandler implements Handler
{
    /**
     * 下一个请求类
     * @var Handler
     */
    protected Handler $next;
}

PHP

Copy

具体类

县教育局

代码语言:javascript
复制
/**
 * 县教育局
 */
class CountyEducationBureau extends BaseHandler
{
    /**
     * 下一个请求
     * @return mixed
     * @author chendashengpc
     */
    public function setNext(Handler $handler)
    {
        $this->next = $handler;
    }

    /**
     * 当前处理
     * @return mixed
     * @author chendashengpc
     */
    public function handler()
    {
        echo '我是县教育局,我这办不了,你去市教育局' . PHP_EOL;
        if ($this->next != null) {
            $this->next->handler();
        }

    }
}

PHP

Copy

市教育局

代码语言:javascript
复制
/**
 * 市教育局
 */
class MunicipalEducationBureau extends BaseHandler
{
    /**
     * 下一个请求
     * @return mixed
     * @author chendashengpc
     */
    public function setNext(Handler $handler)
    {
        $this->next = $handler;
    }

    /**
     * 当前处理
     * @return mixed
     * @author chendashengpc
     */
    public function handler()
    {
        echo '我是市教育局,我这办不了,你去省教育局' . PHP_EOL;
        if ($this->next != null) {
            $this->next->handler();
        }
    }
}

PHP

Copy

省教育局

代码语言:javascript
复制
/**
 * 省教育局
 */
class ProvincialEducationBureau extends BaseHandler
{

    /**
     * 下一个请求
     * @return mixed
     * @author chendashengpc
     */
    public function setNext(Handler $handler)
    {
        $this->next = $handler;
    }

    /**
     * 当前处理
     * @return mixed
     * @author chendashengpc
     */
    public function handler()
    {
        echo '我是省教育局,我这能办,提交资料就能办了' . PHP_EOL;
    }
}

PHP

Copy

客户端使用

代码语言:javascript
复制
$county = new CountyEducationBureau();
$municipal = new MunicipalEducationBureau();
$provincial = new ProvincialEducationBureau();


$county->setNext($municipal);
$municipal->setNext($provincial);

$county->handler();

PHP

Copy

输出

代码语言:javascript
复制
我是县教育局,我这办不了,你去市教育局
我是市教育局,我这办不了,你去省教育局
我是省教育局,我这能办,提交资料就能办了

UML

UML
UML

优缺点

优点

  • 可以控制请求处理的顺序。
  • 单一职责原则。可对发起操作和执行操作的类进行解耦。
  • 开闭原则。可以在不更改现有代码的情况下在程序中新增处理者。

缺点

  • 部分请求可能未被处理。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 责任链模式
  • 问题
  • 解决方法
  • 结构
  • 代码示例
    • 接口
      • 抽象类
        • 具体类
          • 客户端使用
          • UML
          • 优缺点
            • 优点
              • 缺点
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档